useCallback is the guardian of functional identity. In a world where components re-run constantly, it ensures that your event handlers and logic blocks remain stable, preventing expensive downstream re-renders.
1The Functional Identity Crisis
In JavaScript, functions are objects, and every time a function is defined, a new object reference is created. In React, this means every render creates a 'new' version of your event handlers. While this is usually fine for simple elements, it breaks optimizations like React.memo, which only skips re-renders if props are strictly equal (===). useCallback solves this by caching the function instance itself.
2Coordinating with React.memo
useCallback is rarely used alone; it's the partner of React.memo. When you wrap a child component in React.memo, it will only re-render if its props change. If one of those props is a function defined in the parent, you MUST wrap it in useCallback. Otherwise, the child will re-render every time the parent does, defeating the purpose of the optimization.
