useCallback is a React Hook that lets you cache a function definition between re-renders.
Parameters
T
required
The function value that you want to cache. It can take any arguments and return any values. React will return (not call) your function back to you during the initial render. On subsequent renders, React will return the same function if the dependencies have not changed. Otherwise, it will return the function you passed during the current render.
Array<mixed> | void | null
The list of all reactive values referenced inside the callback code. React will compare each dependency with its previous value using the
Object.is comparison.- If omitted, a new function is created on every render (defeats the purpose)
- If
[](empty array), the function never changes - If
[dep1, dep2], the function updates when dependencies change
Returns
On the initial render,useCallback returns the callback function you passed.
On subsequent renders, it will either return an already stored callback function from the last render (if the dependencies haven’t changed), or return the callback function you passed during this render.
Usage
Skipping re-rendering of components
When you optimize rendering performance, you’ll sometimes need to cache functions that you pass to child components:useCallback is only useful as an optimization when passing functions to components wrapped in memo, or when the function is used as a dependency in other Hooks.Updating state from a memoized callback
Use an updater function to avoid dependencies on state:Preventing an Effect from firing too often
Optimizing a custom Hook
Common Patterns
Event handlers
- Without memo
- With memo
With external store
TypeScript
Generic callbacks
Troubleshooting
My callback runs on every render
Make sure you provided a dependency array:My callback is being created on every render despite dependencies
One of your dependencies might be changing on every render:- Move outside
- Use useMemo
- Don't depend on it
Should I add useCallback everywhere?
No! Only useuseCallback when:
- You’re passing the function to a component wrapped in
memo - The function is a dependency of another Hook (useEffect, useMemo, etc.)
- The function is expensive to create (rare)