高效的Mobx形式(Part 2 - 控制数据变动要领)

在上一部份中,我们研讨了怎样设置MobX状况树并使其可视察。 有了这个,下一步就是最先对变化作出回响反映。 坦率地说,这就是风趣的最先!

MobX保证只需您的相应数据图发作变化,依靠于可视察属性的部份就会自动同步。 这意味着您如今能够专注于对变化做出回响反映并引发的副作用,而不是忧郁数据同步。

让我们深切研讨一下能够引发副作用的种种要领。

运用@action作为进口点

默许情况下,当您修正observable时,MobX将检测并坚持其他依靠的可视察对象同步。 这是同步发作的。 然则,偶然您能够愿望在统一要领中修正多个observable。 这能够会致使多个关照被触发,以至能够会下降您的运用速率。
《高效的Mobx形式(Part 2 - 控制数据变动要领)》

更好的要领是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增加更多视察者以实行种种风趣的事变。 一个异常基本的视察者多是一个控制台纪录器,它只是在可视察的变化时将当前值纪录到控制台。

《高效的Mobx形式(Part 2 - 控制数据变动要领)》

经由过程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)。 不跟踪结果函数,您能够在此处运用其他可视察对象。

《高效的Mobx形式(Part 2 - 控制数据变动要领)》

默许情况下,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触发一次性的副作用

autorunreaction是延续的副作用。 初始化运用程序时,您将建立此类副作用,并希冀它们在运用程序的生命周期内运转。

我之前没有提到的一件事是这两个函数都返回一个处置惩罚器函数。 您能够随时挪用该处置惩罚器函数并作废副作用。

const disposer = autorun(()=>{ 
    /* side-effects based on tracked observables */ 
});

// .... At a later time
disposer(); // Cancel the autorun 

如今我们构建的运用程序有种种用例。 您能够愿望某些副作用仅在您抵达运用程序中的某个点时运转。 另外,您能够愿望这些副作用只运转一次,然后再也不会运转。

《高效的Mobx形式(Part 2 - 控制数据变动要领)》

让我们举一个详细的例子:比如说,当用户抵达运用程序中的某个里程碑时,您愿望向用户显现一条音讯。 此里程碑仅对任何用户发作一次,因而您不愿望设置延续运转的副作用,如autorunreaction。 如今是时刻拿出when 这个API来完成这项工作了。

当拿出两个参数时,就像reaction一样。 第一个(跟踪器函数)应当返回一个布尔值。 当这变成真时,它将运转结果函数,第二个参数为when。 最棒的部份是它会在运转后自动处置惩罚副作用。 因而,无需跟踪处置惩罚器并手动挪用它。

when(()=>this.reachedMilestone, ()=>{
    this.showMessage({ 
        title: 'Congratulations', 
        message: 'You did it!'
    });
})

到目前为止,我们已看到了种种手艺来跟踪对象图上的变化,并对这些变化做出回响反映。 MobX提高了笼统级别,以便我们能够在更高级别举行思索,而没必要忧郁跟踪和对变化做出回响反映的不测复杂性。

我们如今有了一个基本,能够构建依靠于域模子变动的壮大体系。 经由过程将域模子以外的一切内容视为副作用,我们能够供应视觉反应(UI)并实行很多其他运动,如监控,剖析,日记纪录等。

    原文作者:hsgshh5259
    原文地址: https://segmentfault.com/a/1190000016279185
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞