Turns an immutable state object into the state of a component: useModel holds it for the lifetime of the
component and renders again after every transition that changes something, so behaviour defined once as a state
object drives any component that adopts it.
Usage
Declare what the component is responsible for as a state interface, with read-only data and transition methods:
interfaceCounter {
readonlyvalue: number;
up(): this; reset(): this;
}
Give it a factory, which may share the interface name, as types and values live in separate namespaces:
Where a component already answers to Counter, name the factory createCounter: a module cannot import both.
Then read data and transitions off the model: a transition is bound to the state it was read from, so a
zero-argument one goes straight to a handler, and any of them may be stored and passed on:
Every transition starts from the state of the render that read it, so taking one twice lands where once does:
consttwice = () => { up(); // value + 1 up(); // value + 1 again, not value + 2 };
A transition also notifies asynchronously, so data read alongside keeps its earlier value until the next render:
constreport = () => { up(); console.log(value); // still the value before the transition };
Unmounting
A model needs no cleanup when the component goes away, nothing outliving it to detach from: the model, its
observers and the setter they notify become unreachable together. This holds as long as models stay local to the
component, so a model is never parked in a module-level cache or handed to an external store. A transition taken
just before unmounting notifies after it, which the state module absorbs without effect.
Headless component state.
Turns an immutable state object into the state of a component: useModel holds it for the lifetime of the component and renders again after every transition that changes something, so behaviour defined once as a state object drives any component that adopts it.
Usage
Declare what the component is responsible for as a state interface, with read-only data and transition methods:
Give it a factory, which may share the interface name, as types and values live in separate namespaces:
Where a component already answers to
Counter, name the factorycreateCounter: a module cannot import both.Then read data and transitions off the model: a transition is bound to the state it was read from, so a zero-argument one goes straight to a handler, and any of them may be stored and passed on:
Transitions do not accumulate
Every transition starts from the state of the render that read it, so taking one twice lands where once does:
A transition also notifies asynchronously, so data read alongside keeps its earlier value until the next render:
Unmounting
A model needs no cleanup when the component goes away, nothing outliving it to detach from: the model, its observers and the setter they notify become unreachable together. This holds as long as models stay local to the component, so a model is never parked in a module-level cache or handed to an external store. A transition taken just before unmounting notifies after it, which the state module absorbs without effect.