useMemo caches a computed value; useCallback caches a function reference. Both help when expensive work or referential equality matters—typically with React.memo children or stable effect dependencies.
useMemo
const sorted = React.useMemo(() => heavySort(items), [items]);
Recomputes only when items changes. Do not wrap every arithmetic operation—profile first.
useCallback
const onSave = React.useCallback(() => save(draft), [draft]);
Returns the same function identity until draft changes—stops child memo components from rerendering because a new inline function appeared.
When NOT to optimize
- Lists under ~100 items with cheap renders
- Components not wrapped in
memo - Premature optimization before measuring
Interview note
React 19+ compiler efforts may auto-memoize in some setups; still know manual hooks for interviews and legacy codebases.
Self-check
- What problem does
useCallbacksolve for child components? - Why is an empty dependency array dangerous for callbacks that close over props?
Tip: Measure before memoizing—useMemo has its own cost and hurts readability when overused.
Interview prep
- When do useMemo and useCallback help?
When expensive work or stable function references prevent unnecessary child re-renders—profile first; premature memoization adds complexity.