在上一部份中,我们研讨了怎样设置MobX状况树并使其可视察。 有了这个,下一步就是最先对变化作出回响反映。 坦率地说,这就是风趣的最先!
MobX保证只需您的相应数据图发作变化,依靠于可视察属性的部份就会自动同步。 这意味着您如今能够专注于对变化做出回响反映并引发的副作用,而不是忧郁数据同步。
让我们深切研讨一下能够引发副作用的种种要领。
运用@action
作为进口点
默许情况下,当您修正observable时,MobX将检测并坚持其他依靠的可视察对象同步。 这是同步发作的。 然则,偶然您能够愿望在统一要领中修正多个observable。 这能够会致使多个关照被触发,以至能够会下降您的运用速率。
更好的要领是action()
中包装要挪用的要领。 这会在您的要领四周建立一个事件边境,而且一切受影响的observable
将在您实行支配后坚持同步。 请注意,此耽误关照仅适用于当前函数局限中的observable
。 假如您具有修正更多可视察对象的异步支配,则必需将它们包装在runInAction()
中。
class Person {
@observable firstName;
@observable lastName;
// 由于我们在@action中包装了此要领,所以只要在changeName()胜利实行后,fullName才会变动
@action changeName(first, last) {
this.firstName = first;
this.lastName = last;
}
@computed get fullName() {
return `${this.firstName}, ${this.lastName}`;
}
}
const p = new Person();
p.changeName('Pavan', 'Podila');
Actions
是转变Store的切入点。 经由过程运用Actions
,您能够将多个observable更新为原子支配。
尽量防止直接从外部支配
observable
并公然
@action
要领为你做这个转变。 现实上,能够经由过程设置
useStrict(true)
来强制实行此支配。
运用@autorun
触发副作用
MobX确保可视察图形一直坚持一致。 但假如这个天下只是关于可视察的东西,那就不好玩了。 我们须要他们的偕行:视察者使事变变得风趣。
现实上,UI是mobx store
的美化视察者。 运用mobx-react
,您将取得一个绑定库,使您的React组件能够视察存储并在存储变动时自动显现。
然则,UI不是体系中唯一的视察者。 您能够向store
增加更多视察者以实行种种风趣的事变。 一个异常基本的视察者多是一个控制台纪录器,它只是在可视察的变化时将当前值纪录到控制台。
经由过程autorun
,我们能够异常轻松地设置这些视察者。 最快的要领是供应autorun
功用。 MobX会自动跟踪您在此函数中运用的任何可视察对象。 每当它们转变时,你的功用都邑从新实行(也就是自动运转)!
class Person {
@observable firstName = 'None';
@observable lastName = 'None';
constructor() {
// A simple console-logger
autorun(()=>{
console.log(`Name changed: ${this.firstName}, ${this.lastName}`);
});
// 这里会致使autorun()运转
this.firstName = 'Mob';
// autorun()再一次运转
this.lastName = 'X';
}
}
// Will log: Name changed: None, None
// Will log: Name changed: Mob, None
// Will log: Name changed: Mob, X
正如您在上面的日记中所看到的,自动运转将马上运转,而且每次跟踪的可视察量发作变化时也会运转。 假如您不想马上运转,而是仅在发作变动时运转,该怎么办? 请继承浏览。
初次替换后运用reaction
触发副作用
与autorun
比拟,reaction
供应了更细粒度的控制。 起首,它们不会马上运转并守候对跟踪的可视察量的第一次变动。 API也与autorun
略有不同。 在最简朴的版本中,您供应两个输入参数:
reaction(()=> data, data => { /* side effect */})
第一个函数(跟踪函数 tracking function
)应当返回将用于跟踪的数据。 然后将该数据传递给第二个函数(结果函数 effect function
)。 不跟踪结果函数,您能够在此处运用其他可视察对象。
默许情况下,reaction
将不会在第一次运转,并将守候追踪函数的变动。 只要当tracking function
返回的数据发作变化时,才会实行副作用。 经由过程将原始自动运转分解为tracking function
+effect function
,您能够更好地控制现实致使副作用的内容。
import {reaction} from 'mobx';
class Router {
@observable page = 'main';
setupNavigation() {
reaction(()=>this.page, (page)=>{
switch(page) {
case 'main':
this.navigateToUrl('/');
break;
case 'profile':
this.navigateToUrl('/profile');
break;
case 'admin':
this.navigateToUrl('/admin');
break;
}
});
}
navigateToUrl(url) { /* ... */ }
}
在上面的示例中,我在加载“main”页面时不须要导航。 一个reaction
运用的圆满案例。 仅当路由器的页面属性发作变动时,才会导航到特定URL。
以上是一个异常简朴的路由器,具有牢固的页面集。 您能够经由过程向URL增加页面舆图来使其更具可扩展性。 运用这类要领,路由(运用URL变动)会成为变动Store某些属性的副作用。
运用when
触发一次性的副作用
autorun
和reaction
是延续的副作用。 初始化运用程序时,您将建立此类副作用,并希冀它们在运用程序的生命周期内运转。
我之前没有提到的一件事是这两个函数都返回一个处置惩罚器函数。 您能够随时挪用该处置惩罚器函数并作废副作用。
const disposer = autorun(()=>{
/* side-effects based on tracked observables */
});
// .... At a later time
disposer(); // Cancel the autorun
如今我们构建的运用程序有种种用例。 您能够愿望某些副作用仅在您抵达运用程序中的某个点时运转。 另外,您能够愿望这些副作用只运转一次,然后再也不会运转。
让我们举一个详细的例子:比如说,当用户抵达运用程序中的某个里程碑时,您愿望向用户显现一条音讯。 此里程碑仅对任何用户发作一次,因而您不愿望设置延续运转的副作用,如autorun
或reaction
。 如今是时刻拿出when
这个API来完成这项工作了。
当拿出两个参数时,就像reaction
一样。 第一个(跟踪器函数)应当返回一个布尔值。 当这变成真时,它将运转结果函数,第二个参数为when
。 最棒的部份是它会在运转后自动处置惩罚副作用。 因而,无需跟踪处置惩罚器并手动挪用它。
when(()=>this.reachedMilestone, ()=>{
this.showMessage({
title: 'Congratulations',
message: 'You did it!'
});
})
到目前为止,我们已看到了种种手艺来跟踪对象图上的变化,并对这些变化做出回响反映。 MobX提高了笼统级别,以便我们能够在更高级别举行思索,而没必要忧郁跟踪和对变化做出回响反映的不测复杂性。
我们如今有了一个基本,能够构建依靠于域模子变动的壮大体系。 经由过程将域模子以外的一切内容视为副作用,我们能够供应视觉反应(UI)并实行很多其他运动,如监控,剖析,日记纪录等。
- Part 1 – 构建可视察数据
- Part 2 – 控制数据变动要领
- Part 3 – 高阶运用实例