synapse-storage
Version:
Набор инструментов для управления состоянием и апи-запросами
38 lines (33 loc) • 1.88 kB
JavaScript
import { useEffect, useRef, useState } from "react";
/**
* Подписка на Observable из компонента.
*
* `source` — либо готовый `Observable<T>` (например `selector.$`), либо фабрика
* `() => Observable<T>`, собирающая цепочку (`pipe(debounceTime(...))`) при подписке.
*
* До первого эмита возвращается `initialValue`. Подписка снимается на unmount и
* пересоздаётся при смене `deps` (вся цепочка строится заново — актуально для
* операторов с состоянием вроде `debounceTime`/`scan`). Если `deps` не переданы:
* для прямого Observable цепочка пересоздаётся при смене ссылки `source`, для
* фабрики — создаётся один раз.
*
* @template T тип значения потока
*/ function useObservable(source, initialValue, deps) {
const [value, setValue] = useState(initialValue);
// Держим source в ref, чтобы замыкание эффекта всегда читало актуальную фабрику,
// но переподписка управлялась исключительно через deps.
const sourceRef = useRef(source);
sourceRef.current = source;
const effectDeps = deps ?? (typeof source === 'function' ? [] : [
source
]);
useEffect(()=>{
const current = sourceRef.current;
const observable = typeof current === 'function' ? current() : current;
const subscription = observable.subscribe((next)=>setValue(next));
return ()=>subscription.unsubscribe();
}, effectDeps);
return value;
}
export { useObservable };
//# sourceMappingURL=useObservable.js.map