MobX Quick Start Guide
上QQ阅读APP看书,第一时间看更新

when()

As the name suggests, when() only executes the effect-function when a condition is met and automatically disposes the side-effect after that. Thus, when() is a one-time side-effect compared to autorun() and reaction(), which are long-running. The predicate function normally relies on some observables to do the conditional checks. If the observables change, the predicate function will be re-evaluated.

when() takes two arguments, which are as follows:

when(predicate-function, effect-function): disposer-function

predicate-function: () => boolean, effect-function: ()=>{}

The predicate function is expected to return a Boolean value. When it becomes true, the effect function is executed, and the when() is automatically disposed. Note that when() also gives you back a disposer function that you can call to prematurely cancel the side-effect.

In this following code block, we are monitoring the availability of an item and notifying the user when it is back in stock. This is the case of a one-time effect that you don't really have to continuously monitor. It's only when the item count in the inventory goes above zero, that you execute the side-effect of notifying the user. Take a look at this:

import { observable, action, when } from 'mobx';

class Inventory {
@observable items = [];

cancelTracker = null;

trackAvailability(name) {

// 1. Establish the tracker with when
this.cancelTracker = when(
() => {
const item = this.items.find(x => x.name === name);
return item ? item.quantity > 0 : false;
},
() => {
console.log(`${name} is now available`);
},
);
}

@action
addItem(name, quantity) {
const item = this.items.find(x => x.name === name);
if (item) {
item.quantity += quantity;
} else {
this.items.push({ name, quantity });
}
}
}

const inventory = new Inventory();

inventory.addItem('Shoes', 0);
inventory.trackAvailability('Shoes');

// 2. Add two pairs
inventory.addItem('Shoes', 2);

// 3. Add one more pair
inventory.addItem('Shoes', 1);

// Prints:
// Shoes is now available

when() here takes two arguments. The predicate function returns true when the item.quantity is greater than zero. The effect function simply notifies (via console.log) that the item is available in the store. When the predicate becomes true, when() executes the side-effect and automatically disposes itself. Thus, when we add two pairs of shoes into the inventory, when() executes and logs the availability.

Notice that when we add one more pair of shoes into the inventory, no logs are printed. This is because at this time when() has been disposed and is no longer monitoring the availability of Shoes. This is the one-time effect of when().