MobX 🇺🇦

MobX 🇺🇦

  • API 参考
  • 中文
  • 한국어
  • 赞助商
  • GitHub

›提示和技巧

介绍

  • 关于 MobX
  • 关于本文档
  • 安装
  • MobX 的核心

MobX 核心

  • 可观察状态
  • 动作
  • 计算属性
  • 反应 {🚀}
  • API

MobX 和 React

  • React 集成
  • React 优化 {🚀}

提示和技巧

  • 定义数据存储
  • 理解反应性
  • 子类化
  • 分析反应性 {🚀}
  • 带参数的计算属性 {🚀}
  • MobX-utils {🚀}
  • 自定义可观察对象 {🚀}
  • 延迟可观察对象 {🚀}
  • 集合工具 {🚀}
  • 拦截与观察 {🚀}

微调

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

拦截与观察 {🚀}

⚠️ 警告: 拦截和观察是低级实用程序,在实践中不应该需要。请改用某种形式的 反应,因为 observe 不尊重事务,也不支持对更改进行深度观察。使用这些实用程序是一种反模式。如果您打算使用 observe 获取旧值和新值,请改用 reaction。 ⚠️

observe 和 intercept 可用于监视单个可观察对象的更改,但它们不跟踪嵌套的可观察对象。

  • intercept 可用于在将更改应用于可观察对象之前检测和修改更改(验证、规范化或取消)。
  • observe 允许您在更改完成之后拦截更改。

拦截

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

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

  • target: 要保护的可观察对象。
  • propertyName: 可选参数,用于指定要拦截的特定属性。请注意,intercept(user.name, interceptor) 与 intercept(user, "name", interceptor) 从根本上不同。前者尝试向 user.name 内部的当前value 添加拦截器,该值可能根本不是可观察对象。后者拦截对 user 的 name属性的更改。
  • interceptor: 对对可观察对象进行的每次更改都调用的回调。接收一个描述更改的单一更改对象。

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

  1. 按原样从函数中返回接收到的 change 对象,在这种情况下将应用更改。
  2. 修改 change 对象并返回它,例如规范化数据。并非所有字段都可以修改,见下文。
  3. 返回 null,这表示可以忽略更改,并且不应应用。这是一个强大的概念,您可以使用它使您的对象暂时不可变。
  4. 抛出一个异常,例如,如果某些不变式没有满足。

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

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(target, propertyName?, listener, invokeImmediately?)

请参阅上面的通知,请避免使用此 API,而改用 reaction。

  • target: 要观察的可观察对象。
  • propertyName: 可选参数,用于指定要观察的特定属性。请注意,observe(user.name, listener) 与 observe(user, "name", listener) 从根本上不同。前者观察 user.name 内部的当前value,该值可能根本不是可观察对象。后者观察 user 的 name属性。
  • listener: 对对可观察对象进行的每次更改都调用的回调。接收一个描述更改的单一更改对象,但对于封装的可观察对象,它将使用两个参数调用 listener: newValue, oldValue。
  • invokeImmediately: 默认情况下为 false。如果希望 observe 直接使用可观察对象的状态调用 listener,而不是等待第一个更改,请将其设置为 true。并非所有类型的可观察对象都支持(尚未)。

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

observe 在进行更改时对更改做出反应,而像 autorun 或 reaction 这样的反应在更改可用时对新值做出反应。在许多情况下,后者就足够了。

示例

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 is dead. Long live mobx.observe

事件概述

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

  • object: 触发事件的可观察对象。
  • debugObjectName: 触发事件的可观察对象的名称(用于调试)。
  • observableKind: 可观察对象的类型(值、集合、数组、对象、映射、计算属性)。
  • type (string): 当前事件的类型。

以下是每种类型可用的其他字段

可观察对象类型事件类型属性描述拦截期间可用可以被拦截修改
对象添加name正在添加的属性的名称。√
newValue正在分配的新值。√√
更新*name正在更新的属性的名称。√
newValue正在分配的新值。√√
oldValue被替换的值。
数组spliceindexsplice 的起始索引。splice 也会被 push、unshift、replace 等触发。√
removedCount正在移除的项目数量。√√
added正在添加的项目数组。√√
removed已被移除的项目数组。
addedCount已被添加的项目数量。
更新index正在更新的单个条目的索引。√
newValue将要分配的 newValue。√√
oldValue已被替换的 oldValue。
映射添加name已添加的条目的名称。√
newValue正在分配的新值。√√
更新name正在更新的条目的名称。√
newValue正在分配的新值。√√
oldValue已被替换的值。
删除name正在删除的条目的名称。√
oldValue已被移除的条目的值。
封装的可观察对象和计算属性创建newValue创建期间分配的值。仅封装的可观察对象作为 spy 事件可用。
更新newValue正在分配的新值。√√
oldValue可观察对象的前一个值。

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

← 集合工具 {🚀}配置 {🚀} →
  • 拦截
  • 观察
  • 事件概述
MobX 🇺🇦
文档
关于 MobXMobX 的核心
社区
GitHub 讨论 (NEW)Stack Overflow
更多
Star