MobX 中文网

MobX 中文网

  • API 文档
  • Nodejs.cn 旗下网站

›提示与技巧

介绍

  • 关于 MobX
  • 关于本文档
  • 安装
  • MobX 的要点

MobX 核心

  • 可观察状态
  • 操作
  • 计算
  • 反应 {🚀}
  • API

MobX 与 React

  • React 集成
  • React 优化 {🚀}

提示与技巧

  • 定义数据存储
  • 了解反应性
  • 子类化
  • 分析反应性 {🚀}
  • 使用参数进行计算 {🚀}
  • MobX-utils {🚀}
  • 自定义可观察值 {🚀}
  • 惰性可观察量 {🚀}
  • 集合实用程序 {🚀}
  • 拦截和观察 {🚀}

微调

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

子类化

¥Subclassing

limitations 支持子类化。最值得注意的是,你只能覆盖原型上的操作/流程/计算 - 你不能覆盖 字段声明。对子类中重写的方法/getter 使用 override 注释 - 请参见下面的示例。尽量让事情变得简单,并且更喜欢组合而不是继承。

¥Subclassing is supported with limitations. Most notably you can only override actions/flows/computeds on prototype - you cannot override field declarations. Use the override annotation for methods/getters overridden in a subclass - see example below. Try to keep things simple and prefer composition over inheritance.

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

class Parent {
    // Annotated instance fields are NOT overridable
    observable = 0
    arrowAction = () => {}

    // Non-annotated instance fields are overridable
    overridableArrowAction = action(() => {})

    // Annotated prototype methods/getters are overridable
    action() {}
    actionBound() {}
    get computed() {}

    constructor(value) {
        makeObservable(this, {
            observable: observable,
            arrowAction: action
            action: action,
            actionBound: action.bound,
            computed: computed,
        })
    }
}

class Child extends Parent {
    /* --- INHERITED --- */
    // THROWS - TypeError: Cannot redefine property
    // observable = 5
    // arrowAction = () = {}

    // OK - not annotated
    overridableArrowAction = action(() => {})

    // OK - prototype
    action() {}
    actionBound() {}
    get computed() {}

    /* --- NEW --- */
    childObservable = 0;
    childArrowAction = () => {}
    childAction() {}
    childActionBound() {}
    get childComputed() {}

    constructor(value) {
        super()
        makeObservable(this, {
            // inherited
            action: override,
            actionBound: override,
            computed: override,
            // new
            childObservable: observable,
            childArrowAction: action
            childAction: action,
            childActionBound: action.bound,
            childComputed: computed,
        })
    }
}

局限性

¥Limitations

  1. 只有原型上定义的 action、computed、flow、action.bound 可以被子类覆盖。

    ¥Only action, computed, flow, action.bound defined on prototype can be overridden by subclass.

  2. 字段不能在子类中重新注释,override 除外。

    ¥Field can't be re-annotated in subclass, except with override.

  3. makeAutoObservable 不支持子类化。

    ¥makeAutoObservable does not support subclassing.

  4. 不支持扩展内置函数(ObservableMap、ObservableArray 等)。

    ¥Extending builtins (ObservableMap, ObservableArray, etc) is not supported.

  5. 你不能在子类中为 makeObservable 提供不同的选项。

    ¥You can't provide different options to makeObservable in subclass.

  6. 你不能在单个继承链中混合注释/装饰器。

    ¥You can't mix annotations/decorators in single inheritance chain.

  7. 所有其他限制也适用

    ¥All other limitations apply as well

TypeError: Cannot redefine property

如果你看到此内容,你可能正在尝试重写子类 x = () => {} 中的箭头函数。这是不可能的,因为类的所有带注释的字段都是不可配置的(查看限制)。你有两个选择:

¥If you see this, you're probably trying to override arrow function in subclass x = () => {}. That's not possible because all annotated fields of classes are non-configurable (see limitations). You have two options:

1. Move function to prototype and use action.bound annotation instead

class Parent {
    // action = () => {};
    // =>
    action() {}

    constructor() {
        makeObservable(this, {
            action: action.bound
        })
    }
}
class Child {
    action() {}

    constructor() {
        super()
        makeObservable(this, {
            action: override
        })
    }
}

2. Remove action annotation and wrap the function in action manually: x = action(() => {})

class Parent {
    // action = () => {};
    // =>
    action = action(() => {})

    constructor() {
        makeObservable(this, {}) // <-- annotation removed
    }
}
class Child {
    action = action(() => {})

    constructor() {
        super()
        makeObservable(this, {}) // <-- annotation removed
    }
}

← 了解反应性分析反应性 {🚀} →
  • 局限性
    • TypeError: Cannot redefine property
MobX v6.13 中文网 - 粤ICP备13048890号
Nodejs.cn 旗下网站