MobX

MobX

  • API 参考
  • English Doc
  • 赞助商
  • GitHub

›Fine-tuning

Introduction

  • 关于 MobX
  • 关于本文档
  • 安装
  • MobX 主旨

MobX core

  • Observable state
  • Actions
  • Computeds
  • Reactions {🚀}

MobX and React

  • 集成React(react-integration)
  • React 优化 {🚀}

Tips & Tricks

  • 定义数据存储
  • 理解响应性
  • 使用子类
  • 分析响应性 {🚀}
  • 含参数的计算值 {🚀}
  • MobX-utils {🚀}
  • 自定义 observables {🚀}
  • 惰性 observables {🚀}
  • 集合工具 {🚀}
  • 拦截与观察 {🚀}

Fine-tuning

  • 配置 {🚀}
  • 启用装饰器语法 {🚀}
  • 从MobX 4/5迁移 {🚀}

Others

  • 链接
Edit

启用装饰器语法

启用装饰器

历经多年改造,ES 装饰器终于到达 TC39 流程的 Stage 3,意味着它们已经非常稳定,并不再有装饰器提案早期版本的不兼容变更。MobX 已实现对“2022.3/Stage 3”新装饰器语法的支持。有了现代装饰器,我们不再需要调用 makeObservable、makeAutoObservable。

2022.3 版装饰器支持情况:

  • TypeScript(5.0 及更新,并确保 experimentalDecorators 选项是禁用的)。示例提交。
  • 对于 Babel,确保 proposal-decorators 插件以最高版本启用 (当前是 2023-05)。示例提交.
// tsconfig.json
{
    "compilerOptions": {
        "experimentalDecorators": false /* 或直接移除该选项 */
    }
}

// babel.config.json(或等价的)
{
    "plugins": [
        [
            "@babel/plugin-proposal-decorators",
            {
                "version": "2023-05"
            }
        ]
    ]
}

使用装饰器

import { observable, computed, action } from "mobx";

class Todo {
    id = Math.random();
    @observable accessor title = "";
    @observable accessor finished = false;

    @action
    toggle() {
        this.finished = !this.finished;
    }
}

class TodoList {
    @observable accessor todos = [];

    @computed
    get unfinishedTodoCount() {
        return this.todos.filter((todo) => !todo.finished).length;
    }
}

注意在使用 @observable 时的 accessor 新关键字用法。它是 2022.3 版规范的一部分,也是你使用现代装饰器的必需品。

使用旧版装饰器

我们不推荐代码库使用 TypeScript / Babel 旧版装饰器,因为它们永远不会成为语言的正式部分,但你仍可使用它们。它确实需要特定的转译设置:

MobX 6 之前的版本鼓励使用旧版装饰器,并将事物标记为 observable、computed 和 action。虽然 MobX 6 建议不要使用这些装饰器(而是使用现代装饰器或 makeObservable、makeAutoObservable),但它在当前大版本依然可用。对旧版装饰器的支持将在 MobX 7 被移除。

import { makeObservable, observable, computed, action } from "mobx";

class Todo {
    id = Math.random();
    @observable title = "";
    @observable finished = false;

    constructor() {
        makeObservable(this);
    }

    @action
    toggle() {
        this.finished = !this.finished;
    }
}

class TodoList {
    @observable todos = [];

    @computed
    get unfinishedTodoCount() {
        return this.todos.filter(todo => !todo.finished).length;
    }

    constructor() {
        makeObservable(this);
    }
}

从旧版装饰器迁移

从旧版装饰器迁移到现代装饰器,需执行以下步骤:

  1. 从你的 TypeScript 配置(或 Babel 等价配置)中禁用或删除 experimentalDecorators 选项
  2. 从使用装饰器的类的构造函数中移除所有 makeObservable(this) 调用
  3. 将 @observable(及其变体)的所有实例替换为 @observable accessor

装饰器变更、陷阱

MobX 2022.3 装饰器与 MobX 5 的非常相似,所以大多数用法是相同的,但是有一些陷阱:

  • @observable accessor 装饰器是 不可 枚举的。accessor 没有一个与过去直接等价的事物 —— 它们是一个语言中的新概念。我们使它们成为不可枚举、非自有属性,以便更好地遵循 ES 语言的精神和 accessor 的含义。可枚举性的主要案例似乎是围绕序列化和剩余解构的。
    • 关于序列化,隐式序列化所有属性在 OOP 世界中可能并不理想,因此这似乎不是一个重大问题(考虑实现 toJSON 或使用 serializer 作为可能的替代方案)
    • 至于解决剩余解构,这在 MobX 中是一个反模式 —— 这么做会(非预期地)触及所有可观察数据并让观察者过度反应。
  • 如果 makeObservable() 被启用,@action some_field = () => {} 曾是并仍是可用的。然而,@action accessor some_field = () => {} 从不可用。

将 observer 用作装饰器

来自 mobx-react 的 observer 函数既是一个普通函数,又是一个可用在类组件的装饰器:

@observer
class Timer extends React.Component {
    /* ... */
}
← 配置 {🚀}从MobX 4/5迁移 {🚀} →
  • 启用装饰器
  • 使用装饰器
  • 将 observer 用作装饰器
MobX
Docs
About MobXThe gist of MobX
Community
GitHub discussions (NEW)Stack Overflow
More
Star