Re-render for what you read
A component shouldn't re-render for a value it never reads.
Paco Courseypaco.meif you never use a certain value, why re-render when that value changes?
Paco Courseypaco.meWhen proxy get is invoked: track which object key is used, return the value
Plain JS here, no React: the same idea as the hook getter.
1 · Change one value
Press a button. Count which widgets flash.
Notify everyoneBad
for (const s of subs) s.run()Renders0Notify readers onlyGood
if (s.keys.has(key)) s.run()Renders0function createStore(initial) {
const state = { ...initial };
const subs = new Set();
const set = (key, value) => {
if (state[key] === value) return;
state[key] = value;
for (const sub of subs) if (sub.keys.has(key)) sub.run();
};
const subscribe = (render) => {
const sub = { keys: new Set(), run: () => {} };
const proxy = new Proxy(state, {
get(target, key) { sub.keys.add(key); return target[key]; },
});
sub.run = () => { sub.keys.clear(); render(proxy); };
subs.add(sub);
sub.run();
return () => subs.delete(sub);
};
return { set, subscribe };
}
Why it matters, pros and cons
Why it matters
Every extra render is wasted work, and the reads already say which values matter.
Pros
- Subscriptions come from the render itself, so no selector list to keep in sync.
- Unrelated updates cost zero renders, however many components subscribe.
- Conditional reads work: keys are cleared and tracked again on every render.
Cons
- Proxy traps add overhead and hide the dependency list from the reader.
- Reads outside render, like in effects or event handlers, are not tracked.
- Spreading the whole state up front reads every key and defeats the point.