import { Dispatch, SetStateAction, useCallback, useDebugValue } from 'react'; import { InitializerOrValue } from '../utils/is-initializer'; import { isSetStateAction } from '../utils/is-set-state-action'; import { Defined, isDefined } from '../utils/type-utils'; import { StateWire } from './state-wire'; import { useStateWire } from './use-state-wire'; import { useWireValue } from './use-wire-value'; type valueAndAction = [V, Dispatch>>]; export function useWireState(upLink: StateWire): valueAndAction; export function useWireState( wire: StateWire | null | undefined, initialValue: InitializerOrValue, ): valueAndAction; export function useWireState( wire: StateWire | null | undefined, initialValue: InitializerOrValue, ): valueAndAction; export function useWireState( wire: StateWire | null | undefined, initialValue?: InitializerOrValue, ): valueAndAction; export function useWireState( wire: StateWire | null | undefined, initialValue?: InitializerOrValue, ): valueAndAction | valueAndAction { const innerWire = useStateWire(wire, initialValue); const valueToReturn = useWireValue(innerWire); useDebugValue(valueToReturn); const setValue = useCallback( (value: SetStateAction>) => { let nextValue = undefined; if (isSetStateAction(value)) { const preValue = innerWire.getValue(); if (isDefined(preValue)) { nextValue = value(preValue); } } else { nextValue = value; } if (isDefined(nextValue)) { innerWire.setValue(nextValue); } }, [innerWire], ); return [valueToReturn, setValue]; }