UNPKG

@supunlakmal/hooks

Version:

A collection of reusable React hooks

38 lines 2.25 kB
import { useRef, useEffect, useCallback } from 'react'; /** * Creates a stable callback function that always calls the latest version of the provided callback. * * Useful for optimizing child components that rely on stable function references (e.g., in `React.memo` or dependency arrays) * while ensuring the most up-to-date logic is executed. * * @template T Callback function type. * @param {T} callback The callback function whose latest version should always be invoked. * @returns {T} A stable function reference that delegates to the latest `callback`. */ export function useEventCallback(callback) { const callbackRef = useRef(callback); // Use useEffect to update the ref whenever the callback changes. // Using useEffect instead of useLayoutEffect to avoid potential warnings during SSR, // as the callback ref update doesn't typically need to be synchronous with layout. useEffect(() => { callbackRef.current = callback; }, [callback]); // Create a stable useCallback wrapper that reads the latest callback from the ref. const memoizedCallback = useCallback((...args) => { // Note: Using optional chaining and a check in case the hook is somehow called // before the initial useEffect runs, though typically callbackRef will be initialized. const currentCallback = callbackRef.current; if (currentCallback) { return currentCallback(...args); } // Consider throwing an error or returning undefined/null if callback is unexpectedly missing, // depending on desired strictness. // console.warn('useEventCallback invoked before callback ref was set.'); // If the callback is truly missing, the function signature requires a return of type ReturnType<T>. // For now, we assume it's always present after the first effect. If not, an error should likely be thrown. // Throwing an error here if currentCallback is null/undefined might be the safest default. throw new Error('useEventCallback: Attempted to call callback before it was set.'); }, []); // No dependencies: the function identity remains stable return memoizedCallback; } //# sourceMappingURL=useEventCallback.js.map