Search documentation

Search all pages, headings and text, in the current package or topic or in all documentation.

Stores and derived values

When a write is accepted and published, how equality decides it, and how derived values stay current.

@workspace/active-state 1.0.1Developmentunreleased, in development in Foundationbaseline ce081dc3

A store holds one value#

TypeScript
import {shallow, Store} from '@workspace/active-state';
const filters = new Store({query: '', page: 1}, {equal: shallow});
filters.setState({query: 'pen', page: 1}); // stores the value as givenfilters.update((current) => ({...current, page: current.page + 1})); // from the current valuefilters.state; // {query: 'pen', page: 2}
  • setState(next) stores next exactly as given; it never calls it, also when it is a function.
  • update(fn) stores fn(current). fn runs in a pure context: it may read, not write.
  • subscribe(listener) delivers (value, previous) for each published transition and returns a release function.

Equality is yours to choose. Without equal a store accepts and publishes every write, also an identical value. With equal, a write that is equal to the current value is not accepted and publishes nothing. shallow compares arrays element by element, plain objects key by key, maps, sets, dates (by time) and URLs.

A derived value computes from declared inputs#

TypeScript
import {Derived} from '@workspace/active-state';
const visible = new Derived({  inputs: [filters, products],  compute: (current, list) =>    list.filter((product) => product.name.includes(current.query)),});
  • compute receives the input values in the order of inputs, and nothing else. It must be pure: memory between evaluations belongs in a store.
  • A read is always current, observed or not, also inside a batch or transaction. Reading never creates or consumes a notification.
  • An observed derived value publishes when its settled value differs from the last published one under its equal (default Object.is).
  • Declared inputs cannot form a cycle; a compute that reads its own value through a closure throws DependencyCycleError.

Settle, then publish#

A write marks what depends on it. Subscribers run once per round, after every affected derived value has settled, so a subscriber never sees a new input next to a stale derived value. A write from a subscriber starts a following round.

Effects react to published values#

An Effect runs after the subscribers of a round in which one of its inputs published. It belongs to a Scope, may return a cleanup, and must be synchronous:

TypeScript
import {Effect, Scope} from '@workspace/active-state';
const scope = new Scope();new Effect({  scope,  inputs: [filters],  immediate: true,  run: ([current]) => {    document.title = current.query ? `Search: ${current.query}` : 'Search';  },});
scope.dispose(); // stops the effect and runs its cleanup

A store, derived values and useStoreClient

  • Notebook: 4.50

1 item, total 4.50

This page as Markdown