atomComputationEffect
atomComputationEffect
is a hook that lets you implement side effects when an atom is computed.
atomComputationEffect(setup, dependencies?)
function atomComputationEffect(
setup: AtomComputationEffect,
dependencies?: unknown[]
): void
type AtomComputationEffect = () => (void | AtomComputationEffectCleanup)
type AtomComputationEffectCleanup = () => void
Reference
atomComputationEffect(setup, dependencies?)
Call atomComputationEffect
at the top level of your atom to declare a computation effect.
import {atomComputationEffect} from 'reago';
function $atom() {
atomComputationEffect(() => {
// runs on every computation
return () => {
// cleanup runs right before the next computation effect runs
};
});
atomComputationEffect(() => {
// runs only for the first computation
}, []);
atomComputationEffect(() => {
// runs for the first computation, and then when dependencies change
}, [...]);
}
Parameters
setup
: The function with your computation effect logic. It should take no arguments. Yoursetup
function may optionally return a cleanup function that takes no arguments and has no return value.dependencies
: The list of all reactive values referenced inside of thesetup
code. The list of dependencies must have a constant number of items and be written inline like[dep1, dep2, dep3]
. Reago will compare each dependency with its previous value using theObject.is
comparison.
Behavior
Reago computes an atom if it has not been computed yet, or was invalidated. An atom is invalidated when its state or values of atoms it depends on change. To put it simply - if there is a possibility that the value of an atom changed, Reago will recompute it.
atomComputationEffect
is a hook that lets you declare side effects that will run for atom computations. It is not the same as putting your logic inside an atom:
- Computation effects run after computation finishes.
- Computation effects can provide a cleanup function that will run if the current computation effect is about to be replaced with a new computation effect (usually because of a change in
dependencies
).
There are three types of computation effects you can declare.
- If you do not provide
dependencies
at all, the effect will run for each computation. Reago will first run the cleanup function from the previous computation, and then thesetup
from the new computation. - If you provide an empty
dependencies
array, Reago will runsetup
only for the first computation. The cleanup function will run only if the store or the atom itself is destroyed. - If you provide a list of
dependencies
, Reago will run thesetup
function for the first computation, and then on subsequent computations, it will run the old cleanup and the newsetup
only ifdependencies
changed.
Caveats
atomComputationEffect
is a hook, so you can only call it at the top level of your atom. You cannot call it inside loops or conditions.- Computation effects run after the atom computation finishes.
- Computation effects run before mount effects.
Examples
Getting the current unix time
Create an atom that returns the current unix time. Use a computation effect to invalidate the result after a second.
import {atomComputationEffect, atomStore} from 'reago';
function $unixTime() {
const {invalidate} = atomStore();
atomComputationEffect(() => {
const timeout = setTimeout(() => {
invalidate($unixTime);
}, 1000);
return () => clearTimeout(timeout);
});
return Math.floor(Date.now() / 1000);
}
Tracking the window width
Create an atom that returns the window.innerWidth
. Use a computation effect to invalidate the result when browser fires the resize
event.
import {atomComputationEffect, atomStore} from 'reago';
function $windowWidth() {
const {invalidate} = atomStore();
atomComputationEffect(() => {
const handler = () => invalidate($windowWidth);
window.addEventListener('resize', handler, {once: true});
return () => window.removeEventListener('resize', handler);
});
return window.innerWidth;
}