The useCallback hook memoizes callback functions to prevent unnecessary re-renders. Here's when and how to use it effectively.
Basic Usage#
With Dependencies#
With React.memo#
Event Handlers#
With useEffect#
Custom Hooks#
Context Optimization#
Debounced Callbacks#
List Item Callbacks#
Ref Callbacks#
When NOT to Use useCallback#
Best Practices#
When to Use:
✓ Passing callbacks to memoized children
✓ Callbacks in useEffect dependencies
✓ Callbacks in custom hooks
✓ Context provider values
When to Skip:
✓ Simple inline handlers
✓ Components without memo
✓ Dependencies that change often
✓ Very cheap operations
Patterns:
✓ Combine with React.memo
✓ Use functional updates
✓ Minimize dependencies
✓ Consider useReducer for complex state
Avoid:
✗ Premature optimization
✗ Every function needs useCallback
✗ Unstable dependencies
✗ Over-memoization
Conclusion#
useCallback memoizes callback functions to maintain stable references across renders. Use it when passing callbacks to memoized child components (React.memo), when callbacks are dependencies in useEffect, or in custom hooks that return functions. Avoid overusing it for simple cases where re-renders are cheap. The key is measuring performance and applying memoization where it provides measurable benefits.