Have you used React.memo , useCallback , useMemo or any other optimization technique and how you used these in your projects
Yes — but selectively. `React.memo` for genuinely expensive children with stable prop references. `useCallback` for callbacks passed to memo'd children or as effect deps. `useMemo` for measurable expensive derivations. Other levers: virtualization, code splitting, `useDeferredValue`/`startTransition`, Suspense, Server Components. Profile first; the default of nothing is right most of the time.
Interviewers want a real story, not a recital of the API. Pick a concrete case and walk through why you used (or removed) the optimization.
When each tool is the right answer
React.memo
const Row = React.memo(({ item }) => <div>{item.label}</div>);Use when:
- The component is genuinely expensive (heavy children, costly computation).
- Its props are stable (parent uses useMemo/useCallback or stable refs).
- The parent re-renders frequently.
Skip when:
- The component is cheap; memo adds cost > savings.
- Props change every render anyway (new object/array literals); memo bails immediately.
useCallback
const onClick = useCallback((id) => dispatch(select(id)), []);Use when:
- The callback is passed to a memo'd child.
- The callback is an effect dep.
Skip for callbacks only consumed by non-memo'd children — no benefit.
useMemo
const filtered = useMemo(() => items.filter(p), [items, p]);Use when:
- The computation is measurably expensive.
- The derived value is passed to memo'd children or effect deps.
Skip for trivial expressions — {count * 2} in JSX doesn't need useMemo.
useDeferredValue / startTransition
For non-urgent renders triggered by user input — see [[how-would-you-improve-interaction-to-next-paint-inp]].
Virtualization
For long lists. See [[how-would-you-optimize-react-rendering-performance-in-large-lists-eg-10k-rows]].
Code splitting + lazy
Per-route + heavy modals. See [[why-is-code-splitting-better-than-loading-everything-at-once]].
Server Components / streaming SSR
Reduce client JS for non-interactive parts.
A real story (template)
"On the dashboard, the legend component for our chart was re-rendering every time we hovered a data point — 60 renders per second. Profiler showed the legend's render was 4ms each; not slow individually but summed to dropped frames. The data passed in was a new object literal from the parent. Two fixes: useMemo on the data prop in the parent, React.memo on the legend. INP improved 250ms → 90ms. The lesson: stable prop references are required for memo to do anything."
When I've removed memoization
"Inherited a codebase with useCallback on every handler. Profiled — most handlers were passed to non-memo'd children where the wrapping cost > benefit. Removed half the memoization; commit time dropped slightly and the code got more readable."
Anti-patterns
- Memo + new object literal prop (memo always bails).
- useMemo for cheap expressions.
- useCallback on handlers consumed by non-memo'd children.
- React.memo on every component without measuring.
Interview framing
"Yes — but selectively. React.memo for expensive components with stable prop refs, useCallback for callbacks passed to memo'd children or used as effect deps, useMemo for measurably expensive derivations. Profile first — memo costs allocation + comparison; if savings don't beat that, you've made things worse. Real wins usually come from structural fixes: virtualization, code splitting, useDeferredValue, RSC. I've removed unnecessary memoization more often than I've added it. Story: stable prop refs are required for memo to actually do anything — a new object literal in the parent defeats it."
Follow-up questions
- •Have you removed useMemo / useCallback in a codebase? Why?
- •When does memo defeat itself?
- •What's a structural perf fix you've made?
Common mistakes
- •Memo + inline object props.
- •useCallback everywhere reflexively.
- •useMemo for cheap expressions.
Performance considerations
- •Memo wins only on measured hot paths with stable refs. Structural fixes (virtualization, RSC) outperform micro-memo.
Edge cases
- •Memo'd component with children prop — children change references unless lifted.
- •Custom equality on memo for object props.
- •useEvent / useEffectEvent (React 19 RFC) as alternative to useCallback for stable callbacks.
Real-world examples
- •TanStack Virtual rows, charting libraries, design system primitives.