Question presented to candidate:
"A component reads only user from a context, but it re-renders every time the theme changes. It is wrapped in React.memo. Why, and how do you fix it?"
What a strong answer should cover:
- React tracks which components read a context and marks all of them for re-render when the provider value changes. It does not know which part of the value each one read.
memodoes not help — context propagation bypasses the props comparison entirely, because the value did not arrive through props.- The value is compared by reference with
Object.is, so a fresh object literal as the provider value is always a change. - Fix 1: memoise the value. Removes re-renders caused by the provider merely re-rendering.
- Fix 2: split the context by change frequency. The only fix for "I read one field and re-render for another".
- Fix 3: separate state and dispatch contexts.
dispatchnever changes identity, so components that only dispatch never re-render. - Fix 4: pass children through. A provider taking
childrendoes not re-render the subtree it wraps. - Fix 5: a store with selectors — Redux, Zustand, Jotai, or
useSyncExternalStore— when you genuinely need field-level subscriptions. - The framing: Context has no selector mechanism, and that is the whole problem.
Clarifying questions expected:
- "Does the consumer read one field of a larger object, or the whole thing?"
- "How often does the value actually change?"
Code / implementation expected: Yes — the split-context fix, ideally with visible render counts.