External Hooks
useCallbackEvent
The API useCallbackEvent
useCallBackEvent
A hook that ensures callback functions always reference the latest version without causing component re-renders, similar to React's experimental useEffectEvent.
Features
- ✅ Always calls the latest callback function
- 🎯 Stable function reference (doesn't change between renders)
- 🚀 Prevents unnecessary re-renders in child components
- 🔄 Solves closure issues with callbacks
When to Use
- Event handlers passed to memoized child components
- Callbacks in
useEffectthat need access to latest state - Functions passed to third-party libraries or event listeners
- Avoiding stale closure problems
Installation
Open inpnpm dlx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useCallbackEvent.jsonnpx shadcn@latest add https://shadcn-ahooks.vercel.app/r/useCallbackEvent.jsonyarn shadcn@latest add https://shadcn-ahooks.vercel.app/r/useCallbackEvent.jsonbun shadcn@latest add https://shadcn-ahooks.vercel.app/r/useCallbackEvent.jsonUsage
Examples
Basic Usage - Solving Stale Closure
Preventing Re-renders with Memoized Children
With Event Listeners
With Third-Party Libraries
API
const stableCallback = useCallbackEvent<T>(callback: T): TParams
| Property | Description | Type | Required |
|---|---|---|---|
| callback | The callback function to wrap | (...args: any[]) => any | Yes |
Result
| Property | Description | Type |
|---|---|---|
| stableCallback | A stable function reference that always calls the latest callback | (...args: any[]) => any |
Comparison with Other Approaches
vs useCallback
// useCallback: Need to include all dependencies
const callback = useCallback(() => {
console.log(stateA, stateB, stateC);
}, [stateA, stateB, stateC]); // Re-creates when any dep changes
// useCallbackEvent: Always stable, always latest
const callback = useCallbackEvent(() => {
console.log(stateA, stateB, stateC);
}); // Never re-createsvs useRef
// useRef: Manual management, verbose
const callbackRef = useRef(callback);
useEffect(() => {
callbackRef.current = callback;
}, [callback]);
const stableCallback = useCallback((...args) => {
return callbackRef.current(...args);
}, []);
// useCallbackEvent: Simple and clean
const stableCallback = useCallbackEvent(callback);How It Works
- Stores Latest Callback: Uses
useImperativeHandleto store the current callback - Stable Wrapper: Returns a memoized function (via
useCallbackwith empty deps) - Latest Execution: The wrapper always calls the stored latest callback
- No Re-creation: The returned function reference never changes
Notes
- This is similar to React's experimental
useEffectEventhook (not yet stable) - The returned function reference is stable and won't cause re-renders
- The callback always has access to the latest props, state, and context
- Perfect for event handlers, callbacks in effects, and third-party library integrations
- Throws an error if called when the callback reference is null (edge case protection)
TypeScript
function useCallbackEvent<T extends (...args: unknown[]) => unknown>(
callback: T
): (...args: Parameters<T>) => ReturnType<T>;The hook is fully typed and preserves the callback's parameter and return types.