Custom operator
All atoms and actions by default include the pipe operator for easy extending and composing. You can create your own operators to enhance your code and make it more modular.
We assume that you’ve already read the core docs.
Prefix and types
#Operator for the pipe function should starts with a verb.
If an operator doesn’t create a new atom and instead mutates the passed one, you should use the with
prefix.
We use T extends Atom
instead of the simpler <T>(length: string): (anAtom: Atom<T>) => Atom<T> & {...}
to preserve all additional properties added by previous operators.
Example
#Advanced example
#This example demonstrates complexity of hotness and coldness of reactive nodes.
Let’s break down the implementation of withReadyAtom
for @reatom/async. That’ll be cool!
First, take a look to the result, then we will disassemble this code step by step:
The logic is simple: the atom represents a flag indicating that the fetching of data has been done (in one way or another). You can find this useful if you are used to code like this:
The native pendingAtom
is not very useful here because it’s 0 by default, and we’ll get a flash of empty content instead of a neat loader during the first render.
Let’s start by defining a generic variable which should have an optional dataAtom
. Otherwise, we’ll have to use @ts-ignore to access this atom. We need this atom to trigger a connection, with something like onConnect(fetchSome.dataAtom, fetchSome)
a resource. Without this, we’ll never touch dataAtom
, thus never trigger fetch and get stuck in a forever-loading state.
Then let’s spy
the pendingAtom
, but we use its value only on the second and following reads of readyAtom
. If it’s the first read, we just show the initial state.
Now we get to an interesting but tricky part. We set onChange
on the atom we just have spied on, but we don’t do anything with this changed value. This trick is needed because of the way atoms get invalidated and because atoms are lazy by default.
When you spy (read and subscribe) on an atom, reatom guarantees you immediate invalidation of the atom. This means that when you change pendingAtom
, every atom spying on it will get invalidated and recalculated when you need their value.
Note that if you try to implement similar behavior only using onChange
, making readyAtom a simple AtomMut<boolean>
without computed bindings, you may get an intermediate invalid state when pendingAtom
has already changed but onChange
has not yet triggered.