React & Modern Frontend (445 Qs)•Part 10: Modern React 18, React 19 & Next.js Patterns (317 - 353)
Does React.memo prevent Context consumers from re-rendering?
No. React.memo only performs a shallow comparison of a component's props — it has no visibility into context. If a component reads a value via useContext/Context.Consumer, that component re-renders whenever the context value changes, regardless of whether it's wrapped in React.memo and regardless of whether its own props changed.
jsx
const CountContext = React.createContext();
// Wrapping with React.memo does NOT help here
const Display = React.memo(function Display() {
const count = useContext(CountContext);
return <div>{count}</div>;
});
function App() {
const [count, setCount] = useState(0);
return (
<CountContext.Provider value={count}>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
<Display />
</CountContext.Provider>
);
}
Every time count changes, Display re-renders even though it takes no props and is memoized — React.memo bails out based on prop equality, but context consumption bypasses that check entirely.
How to actually reduce these re-renders
- Split contexts by concern so a component only subscribes to the slice of state it actually needs (see What's a common pitfall when using useContext with objects?).
- Memoize the provider's value with
useMemoso the reference only changes when the underlying data changes — this reduces churn but doesn't stop consumers from re-rendering when the value itself legitimately changes. - Push
useContextdown into a small wrapper component and pass the extracted value as a prop to a memoized child. The child (wrapped inReact.memo) will now correctly skip re-rendering when that specific prop hasn't changed, since the memoization check happens one level below the context read. - Use a state management library or selector-based API (Redux's
useSelector, Zustand, Jotai) when you need fine-grained, per-field subscriptions instead of one large context object.