Categories
Mobx

Watching MobX Observables with the Autorun Function

Spread the love

We can create Observable objects with MobX. To watch it for changes, we can use the autorun function.

In this article, we’ll look at how to use the autorun function to watch for value changes in MobX Observables.

Autorun

mobx.autorun is used in cases where we want to create a reactive function that doesn’t have an observer itself.

It’s needed for situations like logging, persistence, or UI-updating code.

When autorun is used, the provided function will always be triggered once immediately and then again each time one of its dependencies changes.

computed creates functions that only re-evaluate if it has observers on its own. Therefore, autorun is useful for cases where the Observables don’t have its own observer.

The autorun function returns a disposer function, which is used to dispose of the autorun when we no longer need it.

The reaction itself will be passed as its only argument of the callback function we pass into autorun .

Therefore, we can dispose of autorun by writing:

const disposer = autorun(reaction => {});
disposer();

autorun(reaction => {
  reaction.dispose();
});

autorun will only observe data that are used during the execution of the provided function.

For example, we can write the following:

import { autorun, observable, computed } from "mobx";

const numbers = observable([4, 5, 6]);
const sum = computed(() => numbers.reduce((a, b) => a + b, 0));

const disposer = autorun(() => console.log(sum.get()));
numbers.push(7);

to watch the value of sum , which is a computed value derived from the numbers Observable array.

Options

The autorun function takes a variety of options that can be passed in as the properties of an object as the second argument.

They’re the following:

  • delay — number of milliseconds that can be used to debounce the callback function. Defaults to 0, which means no delay
  • name — string that’s used as the name in various situations like spy events
  • onError — function that’ll handle the errors of the reaction, rather than propagation them
  • scheduler — set a custom scheduler to determine how re-running autorun should be scheduled. The value is a function that has the run callback as a parameter like { scheduler: run => { setTimeout(run, 500) }} .

onError

We can use onError as follows:

import { autorun, observable } from "mobx";

const numFruits = observable.box(10);

const dispose = autorun(
  () => {
    if (numFruits.get() < 0) {
      throw new Error("numFruits should not be negative");
    }
    console.log("Age", numFruits.get());
  },
  {
    onError(e) {
      window.alert("Please enter a valid number");
    }
  }
);

numFruits.set(-1);
dispose();

In the code above, the line:

numFruits.set(-1);

will trigger the ‘Please enter a valid number’ alert to be displayed since we have:

if (numFruits.get() < 0) {
  throw new Error("numFruits should not be negative");
}

in the autorun callback. Therefore, the error will be caught by our onError handler.

We can also set a global error handler by setting the onReactionError function.

Conclusion

We can create an Observable and watch its value with the autorun function. It’s useful for Observables that don’t have an observe method.

It takes a callback with the reaction parameter that we can use to call dispose to dispose of the autorun.

The value of the Observable will be retrieved automatically if we reference it in the callback. As the value of the Observable changes, the autorun callback will run.

It also takes a variety of options like delay, onError handler, and more.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *