import { useEffect , useRef } from 'react' ; import { useMemoOne } from 'use-memo-one' ; import { ObservedTuple , OTuple } from '../core' ; import { AnyArray } from '../shared' ; import { useForceUpdate } from './common' ; /**
 * The given function is called whenever its array of inputs (which may or
 * may not contain observable values) is changed.
 *
 * The caller is re-rendered when the result is _not_ strictly equal to the
 * previous result.
 *
 * If none of the inputs will ever be an observable value, you should avoid
 * using this hook.
 */ export function useDerived < T extends AnyArray , U > ( derive , inputs ) { const target = useMemoOne ( ( ) => new OTuple ( inputs ) , inputs ) ; const result = useRef < U > ( undefined as any ) ; useMemoOne ( ( ) => { result . current = derive ( ... ( target . get ( ) as any ) ) ; } , [ target , derive ] ) ; const forceUpdate = useForceUpdate ( ) ; useEffect ( ( ) => { return target . tap ( ( ) => { const nextResult = derive ( ... ( target . get ( ) as any ) ) ; if ( result . current !== nextResult ) { result . current = nextResult ; forceUpdate ( ) ; } } ) . dispose ; } , [ target , derive ] ) ; return result . current ; }