import { isFunction, ObservableReadable, observe, ObserveEvent, ObserveEventCallback, Selector, } from '@legendapp/state'; import { useRef } from 'react'; import type { ObserveOptions } from '../observe'; import { useEffectOnce } from './useEffectOnce'; export function useObserveEffect(run: (e: ObserveEvent) => T | void, options?: ObserveOptions): void; export function useObserveEffect( selector: Selector, reaction?: (e: ObserveEventCallback) => any, options?: ObserveOptions, ): void; export function useObserveEffect( selector: Selector | ((e: ObserveEvent) => any), reactionOrOptions?: ((e: ObserveEventCallback) => any) | ObserveOptions, options?: ObserveOptions, ): void { let reaction: ((e: ObserveEventCallback) => any) | undefined; if (isFunction(reactionOrOptions)) { reaction = reactionOrOptions; } else { options = reactionOrOptions; } const ref = useRef<{ selector: Selector | ((e: ObserveEvent) => T | void) | ObservableReadable; reaction?: (e: ObserveEventCallback) => any; }>({ selector }); ref.current = { selector, reaction }; useEffectOnce(() => observe( ((e: ObserveEventCallback) => { const { selector } = ref.current as { selector: (e: ObserveEvent) => T | void }; return isFunction(selector) ? selector(e) : selector; }) as any, (e) => ref.current.reaction?.(e), options, ), ); }