Skip to content

Instantly share code, notes, and snippets.

@leonadler
Forked from Alx-l/index.tsx
Last active October 20, 2021 09:02
Show Gist options
  • Select an option

  • Save leonadler/761f75b66ca786f65638dc637ef329c6 to your computer and use it in GitHub Desktop.

Select an option

Save leonadler/761f75b66ca786f65638dc637ef329c6 to your computer and use it in GitHub Desktop.
React useMemoizedCallback hook
import * as React from "react";
// see: https://stackoverflow.com/questions/55045566/react-hooks-usecallback-causes-child-to-re-render/55047178
/**
* Useful when you when to pass a function that depends on a piece of state,
* as a prop, without triggering a re-render everytime.
*
* @example
*
* function SomeComponent() {
* const bar = useMemoizedCallback((value: T) => {
* // do stuff, update state
* }, [someState]);
*
* return <OtherComponent onChange={bar} />
* }
*
*/
export function useMemoizedCallback<A extends unknown[]>(
callback: (...args: A) => void,
dependencyList: ReadonlyArray<unknown>
) {
// Instance to hold the actual callback.
const callbackRef = React.useRef(callback);
// The memoized callback that won't change and calls the changed callbackRef.
const memoizedCallback = React.useCallback((...args: A) => {
return callbackRef.current(arg);
}, []);
// The callback that is constantly updated according to the dependencies.
const updatedCallback = React.useCallback(callback, dependencyList);
// The effect updates the callbackRef depending on the dependencies.
React.useEffect(() => {
callbackRef.current = updatedCallback
}, dependencyList);
// Return the memoized callback.
return memoizedCallback;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment