useCallback
useCallback caches a function definition between renders to maintain stable reference equality.
Mental Model
"The Reusable Stamp: Instead of hand-signing each document with a slightly different signature, you use a stable rubber stamp."
Interactive Engine Simulation
Invariant:The stability of this sequence is what allows React to persist state across asynchronous render cycles.
Executable Code Snippet
1function Parent() {
2 // useCallback caches the function instance
3 const handleAction = useCallback(() => {
4 console.log("Action triggered");
5 }, []);
6
7 return <ExpensiveChild onAction={handleAction} />;
8}
9
10const ExpensiveChild = React.memo(({ onAction }) => {
11 return <button onClick={onAction}>Click Me</button>;
12});- 01.Component re-renders are triggered by state or prop changes.
- 02.Reconciliation algorithm diffs the Virtual DOM to minimize actual DOM updates.
- 03.Automatic batching optimizes multiple state updates into a single render cycle.
01. Identity Stability
In JavaScript, `() => ` always creates a **new function reference**. If you pass this function as a prop, the child component will see it as a "new" prop and re-render. `useCallback` ensures that the same function instance is reused between renders.
Reference Comparison
02. Synergy with React.memo
`useCallback` is almost useless on its own. Its primary purpose is to support **React.memo**. If a child isn't wrapped in `memo`, it will re-render anyway, making the stable function reference irrelevant. Use it only when passing handlers to performance-critical components.
Architectural Advice
"Before optimizing with 'useCallback', ask yourself: 'Is this component actually slow?' 90% of the time, the answer is no. Premature optimization leads to harder-to-read code."