Question presented to candidate:
"What is the difference between useMemo and useCallback, and when is each actually worth it?"
What a strong answer should cover:
useMemo(fn, deps)caches the result of callingfn.useCallback(fn, deps)caches the function itself.- They are the same mechanism:
useCallback(fn, deps)is exactlyuseMemo(() => fn, deps). - Both compare dependencies with
Object.isand recompute only when one changes. - Two distinct reasons to use either: avoiding an expensive computation, and preserving referential identity so a memoised child or a dependency array does not see a change.
- The identity reason is by far the more common one in practice.
- Neither is free: both add a dependency array to maintain and a comparison on every render. Applied everywhere they are a net loss.
- They only pay off in specific conditions — a measured expensive computation, or a stable reference genuinely consumed by
React.memo, a dependency array, or a context value. - The React Compiler automates this class of memoisation, making manual use largely redundant in compiled code.
Clarifying questions expected:
- "Am I trying to avoid a computation, or preserve an identity?" — the two motivations lead to different hooks.
- "Have we profiled? Is this actually the bottleneck?"
Code / implementation expected: Yes — both hooks, with visible recompute and identity counts.