Keeping a function's identity stable across re-renders, when identity actually matters.
By default, a function defined inside a component is recreated on every render — a new reference every time, even if its logic never changed. useCallback memoizes that reference, only creating a new one when something in its dependency array changes. That distinction matters specifically when the function's identity is being checked somewhere else — as a dependency in another hook's array, or as a prop passed into a child wrapped in React.memo.
Without useCallback, a new function reference every render defeats React.memo's shallow prop comparison on that child, causing it to re-render anyway despite being memoized. But useCallback isn't free — wrapping every function 'just in case' adds its own overhead without benefit if that function's identity was never actually being checked anywhere, which is a common overuse pattern worth being able to spot.
What you'll walk away knowing