Mirror / Mirrored state
The problem
Query-string state usually starts with a hook that owns a parameter, and the usual things go wrong:
- the URL becomes a second store, so the Model and the address bar disagree;
- every parameter re-implements a codec, a default, and a history policy;
- back and forward loop through a change handler that writes what it just read;
- a preference lives in
localStoragereads scattered through views; - two tabs, or an old link, restore a value over an edit the user just made.
The fix is to keep the Model authoritative and derive the mirror: one writable
projection names the slice, the store is written when the slice changes, and
navigation or a cold load reduces the store back into the Model through
update.