资讯专栏INFORMATION COLUMN

高效的Mobx模式(Part 2 - 掌握数据变更方法)

xinhaip / 331人阅读

摘要:有了这个,下一步就是开始对变化作出反应。请注意,此延迟通知仅适用于当前函数范围中的。最快的方法是提供功能。只有当返回的数据发生变化时,才会执行副作用。最棒的部分是它会在运行后自动处理副作用。构建可观察数据掌握数据变更方法高阶应用实例

在上一部分中,我们研究了如何设置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触发一次性的副作用

autorunreaction是持续的副作用。 初始化应用程序时,您将创建此类副作用,并期望它们在应用程序的生命周期内运行。

我之前没有提到的一件事是这两个函数都返回一个处理器函数。 您可以随时调用该处理器函数并取消副作用。

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

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

现在我们构建的应用程序有各种用例。 您可能希望某些副作用仅在您到达应用程序中的某个点时运行。 此外,您可能希望这些副作用只运行一次,然后再也不会运行。

让我们举一个具体的例子:比如说,当用户到达应用程序中的某个里程碑时,您希望向用户显示一条消息。 此里程碑仅对任何用户发生一次,因此您不希望设置持续运行的副作用,如autorunreaction。 现在是时候拿出when 这个API来完成这项工作了。

当拿出两个参数时,就像reaction一样。 第一个(跟踪器函数)应该返回一个布尔值。 当这变为真时,它将运行效果函数,第二个参数为when。 最棒的部分是它会在运行后自动处理副作用。 因此,无需跟踪处理器并手动调用它。

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

到目前为止,我们已经看到了各种技术来跟踪对象图上的变化,并对这些变化做出反应。 MobX提高了抽象级别,以便我们可以在更高级别进行思考,而不必担心跟踪和对变化做出反应的意外复杂性。

我们现在有了一个基础,可以构建依赖于域模型更改的强大系统。 通过将域模型之外的所有内容视为副作用,我们可以提供视觉反馈(UI)并执行许多其他活动,如监控,分析,日志记录等。

Part 1 - 构建可观察数据

Part 2 - 掌握数据变更方法

Part 3 - 高阶应用实例

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97418.html

相关文章

  • 高效Mobx模式Part 1 - 构建可观察数据

    摘要:高效的模式提供了一种简单而强大的方法来管理客户端状态。允许属性本身可观察,但不允许其任何子节点。默认情况下,仅将引用更改视为更改。构建可观察数据掌握数据变更方法高阶应用实例 起因 很早之前看到的一篇关于mobx的文章,之前记得是有人翻译过的,但是怎么找都找不到,故花了点时间通过自己那半桶水的英文水平,加上Google翻译一下,对于初学者,以及mobx的开发者提供些许帮助。 这里针对已经...

    trigkit4 评论0 收藏0
  • 高效Mobx模式Part 3 高阶应用实例)

    摘要:当树变异时,连接的部分将作出反应并更新以反映变化。接下来,我们必须对这些行动状态发生的变化作出反应。这可用于将工作流转换为其他状态。将其视为产生价值的可观察物。构建可观察数据掌握数据变更方法高阶应用实例 前两部分侧重于MobX的基本构建块。 有了这些块,我们现在可以通过MobX的角度开始解决一些真实场景。 这篇文章将是一系列应用我们迄今为止所见概念的例子。 当然,这不是一个详尽的清单,...

    eccozhou 评论0 收藏0
  • 【用故事解读 MobX源码(三)】 shouldCompute

    摘要:最简单的情况张三的存贷这里我们创建了实例探长实例观察员这个示例和我们之前在首篇文章用故事解读源码一中所用示例是一致的。 ================前言=================== 初衷:以系列故事的方式展现 MobX 源码逻辑,尽可能以易懂的方式讲解源码; 本系列文章: 《【用故事解读 MobX源码(一)】 autorun》 《【用故事解读 MobX源码(二)】...

    JackJiang 评论0 收藏0
  • 【用故事解读 MobX 源码(五)】 Observable

    摘要:前言初衷以系列故事的方式展现源码逻辑,尽可能以易懂的方式讲解源码本系列文章用故事解读源码一用故事解读源码二用故事解读源码三用故事解读源码四装饰器和用故事解读源码五文章编排每篇文章分成两大段,第一大段以简单的侦探系列故事的形式讲解所涉及人物场 ================前言=================== 初衷:以系列故事的方式展现 MobX 源码逻辑,尽可能以易懂的方式...

    leeon 评论0 收藏0
  • Vuex、Flux、Redux、Redux-saga、Dva、MobX

    摘要:也就是说不应该有公开的,所有都应该是私有的,只能有公开的。允许使用方法设置监听函数,一旦发生变化,就自动执行这个函数。用一个叫做的纯函数来处理事件。可以通过得到当前状态。在中,同步的表现就是发出以后,立即算出。 这篇文章试着聊明白这一堆看起来挺复杂的东西。在聊之前,大家要始终记得一句话:一切前端概念,都是纸老虎。 不管是Vue,还是 React,都需要管理状态(state),比如组件之...

    hiYoHoo 评论0 收藏0

发表评论

0条评论

xinhaip

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<