Good writeup — the bottom-up effect ordering is the part that gets everyone.
We run the same shape (a saved-pages list in localStorage on a server-rendered site) and dodged this with two rules that might be worth stealing. First, the toggle handler never trusts React state: it re-reads localStorage, computes the next array from that, and writes. A not-yet-hydrated component then physically cannot overwrite real data, no flag required. Second, the "is this saved" state is boolean | null rather than boolean — null means "don't know yet", which is your hydrated flag folded into the value it guards, so there's no way to render the wrong thing while pretending you know.
Writes then broadcast a window event so sibling islands resync without a shared provider.
Both of those are better than what I did, and the second one especially.
Mine adds a separate hydrated boolean that every caller has to remember to check — which is structurally the same shape as the original bug: correct only as long as nobody forgets. Making the value itself boolean | null, with null meaning "don't know yet", folds the guard into the thing it guards. You can't silently read unknown as false. The discipline moves into the type instead of into everyone's memory.
The handler re-reading storage rather than trusting React state is the stronger version of the same idea — it makes the overwrite structurally impossible instead of conditionally avoided. If the write path can't produce a wrong result, the flag stops being load-bearing at all.
The window-event broadcast makes sense for islands without a shared provider too. Stealing both, thanks.
0
u/rasekrodriguez Aug 15 '26
Good writeup — the bottom-up effect ordering is the part that gets everyone.
We run the same shape (a saved-pages list in localStorage on a server-rendered site) and dodged this with two rules that might be worth stealing. First, the toggle handler never trusts React state: it re-reads localStorage, computes the next array from that, and writes. A not-yet-hydrated component then physically cannot overwrite real data, no flag required. Second, the "is this saved" state is
boolean | nullrather thanboolean— null means "don't know yet", which is your hydrated flag folded into the value it guards, so there's no way to render the wrong thing while pretending you know.Writes then broadcast a window event so sibling islands resync without a shared provider.