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.