The silent lie — when you forget one re-render
Now — the pain. We add a new feature: a "Remove" button in the collection. In the code column, removeFromCollection looks correct:
function removeFromCollection(date) {
favorites = favorites.filter(f => f.date !== date);
renderCollection(); // the row disappears — looks done!
renderHome(); // the counter ticks down
// ...but we FORGOT renderGallery().
}
As you write it, you think about what you see — the collection you're clicking "Remove" in, and the counter. You re-render those — looks finished. But the same picture is also in the gallery, and there its ♡ stayed filled. The app now says "saved" when it isn't.
Reproduce it yourself:
1. Save a picture (its ♡ fills in the gallery).
2. Go to the collection, click "Remove".
3. Go back to the gallery → that same picture STILL has a filled ♡.
No error in the console. No warning. Tests pass (the collection did update). The bug ships, and a user finds it. This is the silent lie: the DOM shows one thing, the data says another.
And the point isn't that you were "careless". The point is structural: every action must know the full set of views depending on the data it touches — and nothing enforces it. The more actions and views, the more "action × view" pairs there are, and forgetting one is only a matter of time.
The cure — in lesson 9. Instead of each action calling each view, the state announces "I changed" once, and every view updates itself. That's subscribe/notify (pub/sub). An action stops caring about views; it only cares about data.
Manual state management doesn't break immediately — it breaks silently and later. "Don't forget to re-render every dependent view" isn't a code rule; it's discipline. And discipline doesn't scale. This is exactly why state-management libraries and frameworks exist — not fashion, but this specific pain.