The useCallback hook returns a memoized callback function that only changes when dependencies change, helping optimize performance.
Basic Usage#
With Dependencies#
Passing to Child Components#
Event Handlers#
With useEffect#
Debounced Callbacks#
useCallback vs useMemo#
Avoiding Common Pitfalls#
With Context#
Custom Hooks with useCallback#
Best Practices#
When to use useCallback:
✓ Passing callbacks to memoized children
✓ Callbacks used in useEffect dependencies
✓ Expensive callbacks that shouldn't recreate
✓ Functions exposed from custom hooks
When NOT to use:
✗ Every function (adds overhead)
✗ Functions not passed to children
✗ Simple components without memo
✗ Handlers for native elements only
Dependencies:
✓ Include all used values
✓ Use functional updates to avoid deps
✓ Keep dependencies minimal
✓ Use stable references
Performance:
✓ Pair with React.memo for children
✓ Profile before optimizing
✓ Don't prematurely optimize
✓ Measure actual performance gains
Conclusion#
useCallback memoizes callback functions to maintain stable references between renders. Use it when passing callbacks to memoized child components, when callbacks are useEffect dependencies, or when building custom hooks. Pair with React.memo for optimal performance. Avoid overusing it—only add useCallback when you have a demonstrated performance need, as unnecessary memoization adds overhead without benefit.