let contextRenders = 0;
// Simulates Provider re-rendering
function Provider(user, children) {
// Bug: new object every render — all consumers re-render
const value = { user, logout: () => console.log('logout') };
return children(value);
}
function Consumer(value) {
contextRenders++;
return value.user.name;
}
const user = { name: 'Alice' };
// Simulates 3 parent renders (e.g., parent state changed but user didn't)
for (let i = 0; i < 3; i++) {
Provider(user, Consumer);
}
console.log(contextRenders); // should be 1, is 3let contextRenders = 0;
// Stable value — only recompute when user changes
function memoizeValue(factory, user) {
if (memoizeValue._prev?.user === user) return memoizeValue._prev.value;
const value = factory(user);
memoizeValue._prev = { user, value };
return value;
}
function Provider(user, children) {
// Fix: stable reference when user is same
const value = memoizeValue(
(u) => ({ user: u, logout: () => console.log('logout') }),
user
);
return children(value);
}
function Consumer(value) {
contextRenders++;
return value.user.name;
}
const user = { name: 'Alice' };
for (let i = 0; i < 3; i++) {
Provider(user, Consumer);
}
console.log(contextRenders);Bug: { user, logout: () => ... } creates a new object on every render. Context consumers compare value reference — new value → all consumers re-render, even though user didn't change.
Explanation: memoizeValue returns the same object when user hasn't changed. Same reference → consumers skip re-render on renders 2 and 3.
Key Insight: In real React: