Short answer
useMemo caches the result of a calculation between renders; useCallback caches a function definition. Use them when a computation is genuinely expensive, or when a stable reference matters — for example, a prop passed to a memoised child or a value in an effect’s dependency array. Adding them everywhere adds complexity without measurable benefit.
Rule of thumb
- Measure first; memoisation is an optimisation, not a default.
- useCallback(fn, deps) is equivalent to useMemo(() => fn, deps).
- Memoising a callback only helps if the receiver checks identity (React.memo, dependency arrays).
How to answer it in an interview
- Mention that newer React tooling (React Compiler) can apply memoisation automatically.
- Give a concrete example: filtering a large list on each keystroke.