MobX 中文网

MobX 中文网

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

›提示与技巧

介绍

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

MobX 核心

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

MobX 与 React

  • React 集成
  • React 优化 {🚀}

提示与技巧

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

微调

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

拦截和观察 {🚀}

¥Intercept & Observe {🚀}

⚠️ 警告:拦截和观察是底层实用程序,在实践中不应该需要。请改用某种形式的 reaction,因为 observe 不尊重事务,也不支持深入观察变化。使用这些实用程序是一种反模式。如果你打算使用 observe 访问旧值和新值,请改用 reaction。⚠️

¥⚠️ Warning: intercept and observe are low level utilities, and should not be needed in practice. Use some form of reaction instead, as observe doesn't respect transactions and doesn't support deep observing of changes. Using these utilities is an anti-pattern. If you intend to get access to the old and new value using observe, use reaction instead. ⚠️

observe 和 intercept 可用于监视单个可观察量的变化,但它们不跟踪嵌套可观察量。

¥observe and intercept can be used to monitor the changes of a single observable, but they don't track nested observables.

  • intercept 可用于在将突变应用于可观察值(验证、标准化或取消)之前检测和修改突变。

    ¥intercept can be used to detect and modify mutations before they are applied to the observable (validating, normalizing or cancelling).

  • observe 允许你在进行更改后拦截更改。

    ¥observe allows you to intercept changes after they have been made.

拦截

¥Intercept

用法:intercept(target, propertyName?, interceptor)

¥Usage: intercept(target, propertyName?, interceptor)

请避免使用此 API。它基本上提供了一些面向方面的编程,创建了很难调试的流程。相反,在更新任何状态之前而不是在更新期间执行数据验证之类的操作。

¥Please avoid this API. It basically provides a bit of aspect-oriented programming, creating flows that are really hard to debug. Instead, do things like data validation before updating any state, rather than during.

  • target:要守护的可观察物。

    ¥target: the observable to guard.

  • propertyName:可选参数指定要拦截的特定属性。请注意,intercept(user.name, interceptor) 与 intercept(user, "name", interceptor) 根本不同。第一个尝试在 user.name 内的当前 value 中添加一个拦截器,这可能根本不是可观察的。后者拦截对 user 的 name 属性的更改。

    ¥propertyName: optional parameter to specify a specific property to intercept. Note that intercept(user.name, interceptor) is fundamentally different from intercept(user, "name", interceptor). The first tries to add an interceptor to the current value inside user.name, which might not be an observable at all. The latter intercepts changes to the name property of user.

  • interceptor:对可观察对象进行的每次更改都会调用回调。接收描述突变的单个更改对象。

    ¥interceptor: callback that is invoked for each change that is made to the observable. Receives a single change object describing the mutation.

intercept 应该告诉 MobX 当前的更改需要发生什么。因此它应该执行以下操作之一:

¥The intercept should tell MobX what needs to happen with the current change. Therefore it should do one of the following things:

  1. 从函数中按原样返回接收到的 change 对象,在这种情况下将应用突变。

    ¥Return the received change object as-is from the function, in which case the mutation will be applied.

  2. 修改 change 对象并返回它,例如标准化数据。并非所有字段都可以修改,请参见下文。

    ¥Modify the change object and return it, for example to normalize the data. Not all fields are modifiable, see below.

  3. 返回 null,这表明可以忽略更改并且不应应用更改。这是一个强大的概念,例如,你可以使用它使对象暂时不可变。

    ¥Return null, this indicates that the change can be ignored and shouldn't be applied. This is a powerful concept with which you can for example make your objects temporarily immutable.

  4. 例如,如果不满足某些不变量,则抛出异常。

    ¥Throw an exception, if for example some invariant isn't met.

该函数返回一个 disposer 函数,可用于在调用时取消拦截器。可以将多个拦截器注册到同一个可观察对象。它们将按照注册顺序被链接起来。如果其中一个拦截器返回 null 或抛出异常,则其他拦截器将不再被评估。还可以在父对象和单个属性上注册拦截器。在这种情况下,父对象拦截器在属性拦截器之前运行。

¥The function returns a disposer function that can be used to cancel the interceptor when invoked. It is possible to register multiple interceptors to the same observable. They will be chained in registration order. If one of the interceptors returns null or throws an exception, the other interceptors won't be evaluated anymore. It is also possible to register an interceptor both on a parent object and on an individual property. In that case the parent object interceptors are run before the property interceptors.

const theme = observable({
    backgroundColor: "#ffffff"
})

const disposer = intercept(theme, "backgroundColor", change => {
    if (!change.newValue) {
        // Ignore attempts to unset the background color.
        return null
    }
    if (change.newValue.length === 6) {
        // Correct missing '#' prefix.
        change.newValue = "#" + change.newValue
        return change
    }
    if (change.newValue.length === 7) {
        // This must be a properly formatted color code!
        return change
    }
    if (change.newValue.length > 10) {
        // Stop intercepting future changes.
        disposer()
    }
    throw new Error("This doesn't look like a color at all: " + change.newValue)
})

观察

¥Observe

用法:observe(target, propertyName?, listener, invokeImmediately?)

¥Usage: observe(target, propertyName?, listener, invokeImmediately?)

请参阅上面的通知,请避免使用此 API 并使用 reaction 代替。

¥See above notice, please avoid this API and use reaction instead.

  • target:观察到的东西。

    ¥target: the observable to observe.

  • propertyName:可选参数来指定要观察的特定属性。请注意,observe(user.name, listener) 与 observe(user, "name", listener) 根本不同。第一个观察 user.name 内当前的 value,这可能根本不是可观察的。后者观察 user 的 name 性质。

    ¥propertyName: optional parameter to specify a specific property to observe. Note that observe(user.name, listener) is fundamentally different from observe(user, "name", listener). The first observes the current value inside user.name, which might not be an observable at all. The latter observes the name property of user.

  • listener:对可观察对象进行的每次更改都会调用回调。接收描述突变的单个更改对象,盒装可观察值除外,它将使用两个参数调用 listener:newValue, oldValue。

    ¥listener: callback that will be invoked for each change that is made to the observable. Receives a single change object describing the mutation, except for boxed observables, which will invoke the listener with two parameters: newValue, oldValue.

  • invokeImmediately:默认为 false。如果你希望 observe 使用可观察对象的状态直接调用 listener,而不是等待第一次更改,请将其设置为 true。尚未得到所有类型的可观察量的支持。

    ¥invokeImmediately: false by default. Set it to true if you want observe to invoke the listener directly with the state of the observable, instead of waiting for the first change. Not supported (yet) by all kinds of observables.

该函数返回一个 disposer 函数,可用于取消观察者。请注意,transaction 不会影响 observe 方法的工作。这意味着即使在事务 observe 内部,也会为每个突变触发其监听器。因此,autorun 通常是 observe 的更强大、更具声明性的替代方案。

¥The function returns a disposer function that can be used to cancel the observer. Note that transaction does not affect the working of the observe method(s). This means that even inside a transaction observe will fire its listeners for each mutation. Hence autorun is usually a more powerful and declarative alternative to observe.

observe 在突变发生时对其做出反应,而像 autorun 或 reaction 这样的反应则在新值可用时对其做出反应。在许多情况下,后者就足够了。

¥observe reacts to mutations when they are being made, while reactions like autorun or reaction react to new values when they become available. In many cases the latter is sufficient.

示例:

¥Example:

import { observable, observe } from "mobx"

const person = observable({
    firstName: "Maarten",
    lastName: "Luther"
})

// Observe all fields.
const disposer = observe(person, change => {
    console.log(change.type, change.name, "from", change.oldValue, "to", change.object[change.name])
})

person.firstName = "Martin"
// Prints: 'update firstName from Maarten to Martin'

// Ignore any future updates.
disposer()

// Observe a single field.
const disposer2 = observe(person, "lastName", change => {
    console.log("LastName changed to ", change.newValue)
})

相关博客:Object.observe 已死。mobx.observe 万岁

¥Related blog: Object.observe is dead. Long live mobx.observe

事件概览

¥Event overview

intercept 和 observe 的回调将接收一个事件对象,该事件对象至少具有以下属性:

¥The callbacks of intercept and observe will receive an event object which has at least the following properties:

  • object:触发事件的可观察值。

    ¥object: the observable triggering the event.

  • debugObjectName:触发事件的可观察对象的名称(用于调试)。

    ¥debugObjectName: the name of the observable triggering the event (for debugging).

  • observableKind:可观察对象的类型(值、集合、数组、对象、映射、计算)。

    ¥observableKind: the type of the observable (value, set, array, object, map, computed).

  • type(字符串):当前事件的类型。

    ¥type (string): the type of the current event.

这些是每种类型可用的附加字段:

¥These are the additional fields that are available per type:

可观察类型事件类型属性描述拦截期间可用可以通过拦截来修改
目的addname正在添加的属性的名称。√
newValue正在分配的新值。√√
更新*name正在更新的属性的名称。√
newValue正在分配的新值。√√
oldValue被替换的值。
数组spliceindex拼接的起始索引。接头也由 push、unshift、replace 等触发。√
removedCount被移除的项目数量。√√
added正在添加项目的数组。√√
removed包含已删除项目的数组。
addedCount添加的项目数量。
updateindex正在更新的单个条目的索引。√
newValue将分配的 newValue。√√
oldValue被替换的旧值。
映射addname添加的条目的名称。√
newValue正在分配的新值。√√
updatename正在更新的条目的名称。√
newValue正在分配的新值。√√
oldValue已被替换的值。
deletename正在删除的条目的名称。√
oldValue已删除条目的值。
盒装和计算的可观测值createnewValue创建期间分配的值。仅可用作盒装可观察量的 spy 事件。
updatenewValue正在分配的新值。√√
oldValue可观察到的先前值。

注意:对象 update 事件不会因更新的计算值而触发(因为这些不是突变)。但可以通过使用 observe(object, 'computedPropertyName', listener) 显式订阅特定属性来观察它们。

¥Note: object update events won't fire for updated computed values (as those aren't mutations). But it is possible to observe them by explicitly subscribing to the specific property using observe(object, 'computedPropertyName', listener).

← 集合实用程序 {🚀}配置 {🚀} →
  • 拦截
  • 观察
  • 事件概览
MobX v6.13 中文网 - 粤ICP备13048890号
Nodejs.cn 旗下网站