We can create Observable objects with MobX. To watch it for changes, we can use the reaction
function.
In this article, we’ll look at how to use the reaction
function to watch for value changes in MobX Observables.
Reaction
We can use the reaction
function as follows:
reaction(() => data, (data, reaction) => { sideEffect }, options?)
The reaction
function is a variation on autorun
that gives more fine-grained control on how an observable will be tracked.
The side-effect won’t be run directly when the observable is created. It’ll run only after the data expression returns a new value for the first time.
Any observables that are accessed while executing the side effect won’t be tracked.
reaction
returns a disposer function.
The second function passed to reaction
will retrieve 2 arguments when it’s run. The first argument is the value returned by the data
function. The second argument is the current reaction
during execution.
The side effect only reacts to data that was accessed in the data expression. It’ll only be triggered when the data returned by the expression has changed. This means that we have to produce things we need on our side effects.
Options
The third argument of reaction
is an options object that can take the following optional options:
fireImmediately
— boolean that indicates the effect function should trigger immediately after the first run of thedata
function. This isfalse
by default.delay
— number of milliseconds that can be used to debounce the effect function. If it’s zero then no debouncing will happenequals
— a compare function that’ll be used to compare the previous and next values produced by thedata
function. Theeffect
function will only be invoked if the function returnsfalse
. Default iscomparer.default
.name
— a string that’s used as the name for the reactiononError
— a function that’ll handle the errors of this reaction, rather than propagating themscheduler
— set a custom scheduler to determine how re-running the autorun function should be scheduled
Usage
We can use the reaction
function as follows:
import { reaction, observable } from "mobx";
const todos = observable([
{
title: "eat"
},
{
title: "drink"
}
]);
reaction(
() => todos.map(todo => todo.title),
titles => console.log(titles.join(", "))
);
todos.push({ title: "sleep" });
In the code above, we created a new observable array using the observable
function, which we assigned to the todos
constant.
Then we call the reaction
function, where we pass a callback to return an array which has the title
strings from the todos
observable array as the first argument.
In the second argument, we get the titles
array returned from the function in the first argument, and the console.log
the titles
array joined together with join
.
Then we call push
on it, as we did in the last line, the new comma-separated string will be logged with the console.log
since we changed it. It won’t log the value when it’s initially created.
Conclusion
We can use the reaction
function to watch for observable variable changes.
It won’t watch for the value when it’s initially created.
reaction
takes a callback to watch the value and return something we want from it. The second argument takes a value that takes the returned value from the first function and then we can perform some side effects on it.
The 3rd argument takes an object that takes a variety of options.