Skip to content

useEventCallback

Edit

Returns a stable callback that always delegates to the latest function.

useEventCallback.ts
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;
}
Terminal
wget -O src/hooks/useEventCallback.ts https://raw.githubusercontent.com/jrTilak/lazykit/HEAD/registry/react-hooks/useEventCallback.ts
useEventCallback.example.tsx
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.

EventCallback<Callback> — A callback with stable identity. After each commit, it invokes the latest callback supplied to the hook.