Question presented to candidate:
"A colleague has wrapped most components in React.memo and the profiler looks the same as before. Why?"
What a strong answer should cover:
memocompares props by reference (a shallow equality check). Any prop that is a new object, array, or function each render fails that check every time.- So the classic no-op is an inline
style={{...}},items={[...]}, oronClick={() => ...}in the parent's JSX — the comparison is guaranteed to fail. - When the comparison always fails,
memois pure overhead: you pay the check and still render. memoalso does nothing if the component re-renders for a different reason — its own state changed, or a context it consumes changed. It only blocks re-renders caused by the parent.- Wrapping cheap components is a net loss: the comparison plus the extra memory can exceed the render it saves.
- A custom comparator can make it worse — deep-comparing a large object every render, or silently going stale if you forget a prop.
- The reliable fixes are stable references (hoist constants,
useCallback,useMemo) or not passing the prop at all (composition viachildren).
Clarifying questions expected:
- "What props does this component receive, and are any of them created inline?"
- "Is the parent re-rendering, or is it this component's own state or context?"
Code / implementation expected: Optional. Showing the inline-prop failure and its hoisted fix is the clearest form.