- MobX Quick Start Guide
- Pavan Podila Michel Weststrate
- 530字
- 2021-08-05 10:34:25
reaction()
reaction() is yet another kind of reaction in MobX. Yes, the choice of the API name was intentional. reaction() is similar to autorun() but waits for a change in the observables before executing the effect-function. reaction() in fact takes two arguments, which are as follows:
reaction(tracker-function, effect-function): disposer-function
tracker-function: () => data, effect-function: (data) => {}
tracker-function is where all the observables are tracked. Any time the tracked observables change, it will re-execute. It is supposed to return a value that is used to compare it to the previous run of tracker-function. If these return-values differ, the effect-function is executed.
By breaking up the activity of a reaction into a change-detecting function (tracker function) and the effect function, reaction() gives us more fine-grained control over when a side-effect should be caused. It is no longer just dependent on the observables it is tracking inside the tracker function. Instead, it now depends on the data returned by the tracker function. The effect function receives this data in its input. Any observables used in the effect function are not tracked.
Just like autorun(), you also get a disposer function as the return-value of reaction(). This can be used to cancel the side-effect anytime you want.
We can put this into practice with an example. Let's say you want to be notified anytime an item in your Cart changes its price. After all, you don't want to purchase something that suddenly shoots up in price. At the same time, you don't want to miss out on a great deal as well. So, getting a notification when the price changes is a useful thing to have. We can implement this by using reaction(), as shown here:
import { observable, action, reaction } from 'mobx';
class Cart {
@observable modified = new Date();
@observable items = [];
cancelPriceTracker = null;
trackPriceChangeForItem(name) {
if (this.cancelPriceTracker) {
this.cancelPriceTracker();
}
// 1. Reaction to track price changes
this.cancelPriceTracker = reaction(
() => {
const item = this.items.find(x => x.name === name);
return item ? item.price : null;
},
price => {
console.log(`Price changed for ${name}: ${price !==
null ? price : 0}`);
},
);
}
@action
addItem(name, price) {
this.items.push({ name, price });
this.modified = new Date();
}
@action
changePrice(name, price) {
const item = this.items.find(x => x.name === name);
if (item) {
item.price = price;
}
}
}
const cart = new Cart();
cart.addItem('Shoes', 20);
// 2. Now track price for "Shoes"
cart.trackPriceChangeForItem('Shoes');
// 3. Change the price
cart.changePrice('Shoes', 100);
cart.changePrice('Shoes', 50);
// Prints:
// Price changed for Shoes: 100
// Price changed for Shoes: 50
In the preceding snippet, we are setting up a price tracker in comment 1, as a reaction to track price changes. Notice that it takes two functions as inputs. The first function (tracker-function) finds the item with the given name and returns its price as the output of the tracker function. Any time it changes, the corresponding effect function is executed.
The console logs also print only when the price changes. This is exactly the behavior we wanted and achieved through a reaction(). Now that you are notified of the price changes, you can make better buying decisions.
- C++黑客編程揭秘與防范
- 工業(yè)控制網(wǎng)絡(luò)安全技術(shù)與實(shí)踐
- 物聯(lián)網(wǎng)之魂:物聯(lián)網(wǎng)協(xié)議與物聯(lián)網(wǎng)操作系統(tǒng)
- OpenLayers Cookbook
- 萬物互聯(lián):蜂窩物聯(lián)網(wǎng)組網(wǎng)技術(shù)詳解
- SSL VPN : Understanding, evaluating and planning secure, web/based remote access
- 物聯(lián)網(wǎng)安全技術(shù)
- Mastering TypeScript 3
- 物聯(lián)網(wǎng)與智能家居
- Echo Quick Start Guide
- 網(wǎng)絡(luò)工程實(shí)施技術(shù)與方案大全
- 轉(zhuǎn)化:提升網(wǎng)站流量和轉(zhuǎn)化率的技巧
- 全聯(lián)網(wǎng)標(biāo)識服務(wù)
- 計算機(jī)通信網(wǎng)絡(luò)安全
- React Design Patterns and Best Practices(Second Edition)