Updating a store
Updating a store in the State with useStore guide.
setStore accepts these forms. Every call is one batched transaction: readers of everything that changed are notified once, and the call itself is untracked.
| Form | Meaning |
|---|---|
setStore({ title: "x" }) |
Merges the keys into the object. For an array store, an array replaces the contents (diffed, see reconcile). |
setStore((draft) => { draft.title = "x"; }) |
Draft: mutate freely (assign, push, splice, delete). Returning a value instead merges it (objects) or reconciles it (arrays). |
setStore("user", "name", "x") |
Path: up to four steps, then a value. Fully type-checked; deeper or dynamic paths go through a draft. |
setStore("count", (n) => n + 1) |
Path ending in an updater (previous) => next. |
setStore("todos", 2, { done: true }) |
Path ending in a partial object: merged into the existing object. Arrays and primitives replace. |
setStore(reconcile(next)) |
Diffs next into the store; retained items keep their identity. |
setStore("todos", reconcile(next)) |
The same, for one sub-tree only. |
setStore(produce((draft) => { ... })) |
produce returns its argument; it exists for code migrated from other libraries. |
Rules of the draft#
- A draft is valid only while the update function runs. Keeping it and writing later throws a
TypeError("a draft was used after its setStore() call returned"). - Reads through a draft are not tracked.
- Writing a value equal to the current one (
Object.is) notifies nothing. - Assign fresh data (
draft.items = [...]with new objects) or change arrays in place (push,splice,sort, index assignment). Do not assign an array that was built from draft items withfilter,maporslice: those items are drafts and are not valid after the update. To keep a filtered subset, usesetStore("items", reconcile(state.items.filter(...)));reconcileunwraps store items. - Path steps and merged keys named
__proto__,constructororprototypethrow aTypeError.
Errors#
Store errors are TypeErrors with a ShadowStore prefix. A path that goes through a value that is not an object, a path step that does not fit the container (a string on an array), and setStore() with no argument all throw. A write to the read-only view throws as well: