Learning
Before we start
#In the examples we will use the @reatom/framework package which is an umbrella package for the most common reatom packages. You can install it with the following command
Basic primitives
#The reatom is based on three basic primitives: Atom
, Action
and Context
.
Below you can see an example of how they are used together.
We’ll break down each line and explain what happens.
Context
#First, we created a context. It is essential for reading, modifying, and subscribing to changes. We’ll explore its cool features later, but for now, remember: one context is enough for the whole application.
Atom
#Create Atom
#An atom is like a variable — it has a type and a value.
However, unlike a regular variable, we can track its changes and react accordingly.
We create an atom using the atom
factory function.
Here’s an example of creating an atom with an initial value of 1
and naming it aAtom
.
The name isn’t required, but it’s super helpful for debugging.
Atoms can also be computed from other atoms.
This line of code means: “To get the value of cAtom
, you need to read the current values of aAtom
and bAtom
and sum them up.”
Computed atoms should be pure functions to ensure the correct order of all computations.
Read Atom
#To read the value of an atom, you need to use the previously created context.
It’s important to note that an atom’s value is retrieved only when read. In other words, if no one has read a computed atom, its associated function won’t run.
Also, If a computed atom doesn’t explicitly track at least one other atom (by spy
), it will recall on each read (get
/ spy
).
Update Atom
#To change the value of an atom, you also need a context. This time, you need to pass the context to the atom.
You can use the current value of the atom in the update operation by passing a function.
You can also use the previous state in computable atoms.
Subscribe to Atom
#Finally, you can subscribe to atom changes using the context.
Actions
#Actions are transactions
#Setting atoms manually is useful, but more often, we want to make multiple changes at once.
Let’s modify the example so we can change aAtom
and bAtom
simultaneously.
As we can see, the subscribe callback is only called when both aAtom
and bAtom
values change.
It’s called a “transaction”.
Transactions help to reduce the number of subscriber calls and prevent the creation of unwanted intermediate states.
Async actions
#Creating asynchronous actions is also possible, but remember that async operations must be called inside the ctx.schedule
callback.
Actions nesting
#You can call actions from other actions. Asynchronous actions will return a promise.
Advanced
#Multiple contexts
#Contexts connect atoms and actions, track transactions, and offer many more features. You can use the same dependency trees in different contexts.
Computed atoms can’t depend on atom values from different contexts, and actions can’t change atoms in a different context. The context will initiate a new item state referring to that atom.
It makes testing easier. However, be cautious with function closures, as they are not context-dependent!