import { useLayoutEffect } from 'react-layout-effect' import { useMemoOne as useMemo } from 'use-memo-one' import { emptyArray } from '../common' import { no } from '../no' import { Change, ChangeObserver, ObserverTarget } from '../observable' import { $O } from '../symbols' /** Listen for shallow changes to an observable object. */ export function useChanges( target: ObserverTarget, onChange: (change: Change) => void, deps?: readonly any[] ) { const observable = target[$O] if (!observable) { throw Error('Expected an observable object') } const observer = useMemo( () => ({ onChange } as any), emptyArray ) useLayoutEffect(() => { observer.onChange = no(onChange) }, deps) useLayoutEffect(() => { const observers = observable.get($O) observers.add(observer) return () => { observers.delete(observer) } }, [observable]) }