Hint
Every render creates new function instances for inline arrow functions. useCallback solves this by returning a cached reference. This is crucial when passing callbacks to React.memo children.
function useCallback(fn, deps) {
let saved = null;
return function get(newDeps) {
if (saved && newDeps.every((d,i) => d === saved.deps[i])) return saved.fn;
saved = { fn, deps: newDeps };
return saved.fn;
};
}
// Inline function: new reference every call
const a1 = (x) => x * 2;
const a2 = (x) => x * 2;
// useCallback: same reference when deps unchanged
const getId = useCallback((id) => id, []);
const ref1 = getId([]);
const ref2 = getId([]);
console.log(a1 === a2); // different inline functions
console.log(ref1 === ref2); // same stable reference
console.log(typeof ref1);false true function
Explanation: a1 and a2 are defined separately — different objects even with same source code. useCallback returns the SAME function reference when deps don't change.
Key Insight: Every render creates new function instances for inline arrow functions. useCallback solves this by returning a cached reference. This is crucial when passing callbacks to React.memo children.