import { useCallback, useLayoutEffect, useRef, type RefObject } from "react"; /** A ref that holds the latest COMMITTED `value`, for a stable callback that must still read fresh * props: an event handler, a timer, an API that takes its callbacks once. When only effects read the * value, use `useEffectEvent` instead. * * Written in a layout effect, never during render. A render-phase `ref.current = value` makes the * React Compiler skip the whole component, and it is wrong under concurrent rendering anyway: * a render React throws away would still have overwritten the value. Read it outside render only. */ export function useLatest(value: T): RefObject { const ref = useRef(value); useLayoutEffect(() => { ref.current = value; }); return ref; } /** A callback with a STABLE identity that always runs the latest `fn` — for a handler handed to * something memoized (a column set, a menu model) that must not rebuild whenever the handler's * inputs change. Call it from events only, never during render: it runs the last COMMITTED `fn`. */ export function useStableCallback( fn: (...args: A) => R, ): (...args: A) => R { const latest = useLatest(fn); return useCallback((...args: A) => latest.current(...args), [latest]); }