useEventCallback
EditReturns a stable callback that always delegates to the latest function.
import { useCallback, useEffect, useLayoutEffect, useRef,} from "react";
type Callable = (...args: never[]) => unknown;
export type EventCallback<Callback extends Callable> = Callback;
const useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
export function useEventCallback<Callback extends Callable>( callback: Callback,): EventCallback<Callback> { const callbackRef = useRef(callback);
useIsomorphicLayoutEffect(() => { callbackRef.current = callback; }, [callback]);
return useCallback(function ( this: unknown, ...args: readonly unknown[] ): unknown { return Reflect.apply(callbackRef.current, this, args); }, []) as unknown as Callback;}Download
Section titled “Download”wget -O src/hooks/useEventCallback.ts https://raw.githubusercontent.com/jrTilak/lazykit/HEAD/registry/react-hooks/useEventCallback.tstemp_dir="$(mktemp -d)" && bunx degit jrTilak/lazykit/registry/react-hooks "$temp_dir" && mv "$temp_dir/useEventCallback.ts" src/hooks/useEventCallback.ts && rm -r "$temp_dir"Examples
Section titled “Examples”import { useState } from "react";
import { useEventCallback } from "./useEventCallback";
export function EventCallbackExample() { const [count, setCount] = useState(0); const announce = useEventCallback(() => { window.alert(`The latest count is ${count}.`); });
return ( <div> <p>Count: {count}</p> <button type="button" onClick={() => setCount((value) => value + 1)}> Increment </button> <button type="button" onClick={announce}> Show latest count </button> </div> );}callback(Callback) — Function to invoke. Its complete callable type, including generic or overloaded signatures and an explicit receiver, is preserved.
Returns
Section titled “Returns”EventCallback<Callback> — A callback with stable identity. After each commit,
it invokes the latest callback supplied to the hook.