title: MobX API 参考 sidebar_label: MobX API 参考

hide_title: true

MobX API 参考

用 {🚀} 标记的函数被视为进阶部分,通常不需要使用。请考虑下载我们的速查表,它用一页篇幅解释了所有重要的 API:

核心 API

这些是 MobX 中最重要的 API。

理解 observablecomputedreactionaction 就足够你掌握 MobX 并在你的应用中使用它了!

创建 observable

把事物转化成 observable。

makeObservable

用法makeObservable(target, annotations?, options?)

属性、整个对象、数组、Maps 和 Sets 都可以被转化成 observable。

makeAutoObservable

用法makeAutoObservable(target, overrides?, options?)

自动把属性、对象、数组、Maps 和 Sets 转化成 observable。

extendObservable

{🚀} 用法:extendObservable(target, properties, overrides?, options?)

可以用来在 target 对象上引入新属性并立即把它们全部转化成 observable。基本上就是 Object.assign(target, properties); makeAutoObservable(target, overrides, options); 的简写。但它不会变动 target 上已有的属性。

老式的构造器函数可以很好地跟 extendObservable 结合起来使用:

  1. function Person(firstName, lastName) {
  2. extendObservable(this, { firstName, lastName })
  3. }
  4. const person = new Person("Michel", "Weststrate")

使用 extendObservable 在一个对象实例化之后再为其添加 observable 字段也是可以的,但要注意,以这种方式添加 observable 属性这一行为本身并不能被观察。

observable

用法observable(source, overrides?, options?)observable(注解)

克隆一个对象并把它转化成 observable。source 可以是一个普通的对象、数组、Map 或 Set。默认情况下,observable 会递归执行。如果遇到的值中有一个是对象或数组,那么该值也会被传入 observable

observable.object

{🚀} 用法observable.object(source, overrides?, options?)

observable(source, overrides?, options?) 的别名。创建一个被传入对象的副本并使它的所有属性 observable。

observable.array

{🚀} 用法:observable.array(initialValues?, options?)

基于所提供的 initialValues 创建一个新的 observable 数组。如果要把 observable 数组转化回普通的数组,就请使用 .slice() 方法,或者参阅 toJS 进行递归转化。除了语言中内置的所有数组方法之外,observable 数组中还有以下好用的工具函数供你使用:

  • clear() 删除数组中所有现存的元素。
  • replace(newItems) 用新元素替换数组中所有现存的元素。
  • remove(value) 从数组中删除一个值为 value 的元素,在找到并删除该元素后返回 true

如果你不想把数组中的值自动转化成 observable,则可使用 { deep: false } 选项将该数组转化成浅层 observable。

observable.map

{🚀} 用法:observable.map(initialMap?, options?)

基于所提供的 initialMap 创建一个新的 observable ES6 Map。如果你不仅想对特定条目的改变作出反应,还想对其添加和删除做出反应的话,那么它们就会变得非常有用。如果你没有启用代理,那么推荐使用创建 observable Maps 的方式来创建动态键控集合。

除了语言中内置的所有 Map 方法之外,observable Maps 中还有以下好用的工具函数供你使用:

  • toJSON() 返回该 Map 的浅层普通对象表示(使用 toJS 进行深拷贝)。
  • merge(values) 将所提供的 values (普通的对象、数组或以字符串为键的 ES6 Map )的所有条目复制到该 Map 中。
  • replace(values) 用所提供的 values 替换该 Map 的全部内容。

如果你不想把 Map 中的值自动转化成 observable,则可使用 { deep: false } 选项将该 Map 转化成浅层 observable。

observable.set

{🚀} 用法:observable.set(initialSet?, options?)

根据所提供的 initialSet 创建一个新的 observable ES6 Set。每当你想创建一个动态集合,并需要观察其内部值的添加和删除,但每个值在整个集合中只能出现一次时,就可以使用它。

如果你不想把 Set 中的值自动转化成 observable,则可使用 { deep: false } 选项将该 Set 转化成浅层 observable。

observable.ref

用法observable.ref(注解)

observable 注解类似,但只有重新赋值会被追踪。所赋的值本身并不会被自动转化成 observable。比如说,你可以在你向一个 observable 字段中储存不可变数据时使用它。

observable.shallow

用法observable.shallow(注解)

observable.ref 注解类似,但用于集合。任何所赋的集合都会被转化成 observable,但是集合本身的内容不会被转化成 observable。

observable.struct

{🚀} 用法observable.struct(注解)

和 observable 注解类似, 但是与现有值结构相等的任何赋值都会被忽略。

observable.deep

{🚀} 用法observable.deep(注解)

observable 注解的别名。

observable.box

{🚀} 用法:observable.box(value, options?)

JavaScript 中的所有原始值都是不可变的,所以它们当然都不是 observable。这一点通常没有问题,因为 MobX 可以把包含该值的属性转化成 observable。在极少数情况下,如果能有独立于对象的 observable 原始值的话就会很方便。对于这种情况,可以创建一个 observable box 来管理这种原始值

observable.box(value) 接受一个任意值并将其存储在一个 box 中。我们可以通过 .get() 对其当前值进行访问,并使用 .set(newValue) 对其进行更新。

  1. import { observable, autorun } from "mobx"
  2. const cityName = observable.box("Vienna")
  3. autorun(() => {
  4. console.log(cityName.get())
  5. })
  6. // Prints: 'Vienna'
  7. cityName.set("Amsterdam")
  8. // Prints: 'Amsterdam'

如果你不想把 box 中的值自动转化成 observable,则可使用 { deep: false } 将该 box 转化成浅层 observable。


Actions

Action 就是任何一段修改状态的代码。

action

用法action(fn)action(注解)

用于意在修改状态的函数。

runInAction

{🚀} 用法runInAction(fn)

创建一个被立即调用的一次性 action。

flow

用法flow(fn)orflow(注解)

对 MobX 友好的 async/await 替代品,支持取消。

flowResult

用法flowResult(flowFunctionResult)

仅供 TypeScript 用户使用。将 generator 的输出结果转化成 promise 的工具函数。这只是一个针对 flow 做的 promise 包装进行的类型上的更正。它在运行时会直接返回被传入其中的值。


计算值

计算值可以用来从其他 observable 中派生出数据。

computed

用法computed(fn, options?)computed(options?)(注解)

创建一个从其他 observable 中派生出来的 observable。但只要底层 observable 不变,这个值就不会被重新计算。


与 React 的整合

来自 mobx-reactmobx-react-lite 包。

observer

用法observer(component)

一个高阶组件,可用来在 observable 发生改变时将一个 React 函数组件或类组件重新渲染。

Observer

用法<Observer>{() => rendering}</Observer>

渲染所提供的 render 函数,并在 render 函数所使用的 observable 之一发生改变时自动将函数重新渲染。

useLocalObservable

用法useLocalObservable(() => source, annotations?)

使用 makeObservable 创建一个新的 observable,并在组件的整个生命周期内将其保留在组件中。


Reactions

Reactions 用来对自动发生的副作用进行建模。

autorun

用法autorun(() => effect, options?)

在被其观察的任意一个值发生改变时重新执行一个函数。

reaction

用法reaction(() => data, data => effect, options?)

在所选的任一数据发生改变时重新执行一个副作用。

when

用法when(() => condition, () => effect, options?)await when(() => condition, options?)

一旦一个 observable 条件为真就立即执行一次副作用函数。


工具函数

这些工具函数可能会使得 observable 或计算值的使用更加方便。你在 mobx-utils 包中也可以找到更复杂的工具函数。

onReactionError

{🚀} 用法:onReactionError(handler: (error: any, derivation) => void)

绑定一个全局错误监听函数。每当一个 reaction 抛出错误时,该监听函数都会被调用。可用于监控或测试。

intercept

{🚀} 用法intercept(propertyName|array|object|Set|Map, listener)

在一个 observable API 发生改变之前将改变拦截。返回一个可以用来中止拦截的 disposer 函数。

observe

{🚀} 用法observe(propertyName|array|object|Set|Map, listener)

底层 API,可用于观察单个 observable。返回一个可以用来中止拦截的 disposer 函数。

onBecomeObserved

{🚀} 用法onBecomeObserved(observable, property?, listener: () => void)

可以在某个值开始被观察时使用的钩子函数。

onBecomeUnobserved

{🚀} 用法onBecomeUnobserved(observable, property?, listener: () => void)

可以在某个值停止被观察时使用的钩子函数。

toJS

用法toJS(value)

将一个 observable 对象递归转化成一种 JavaScript 数据结构。支持 observable 数组、对象、Maps 和原始值。 结果不包含计算值和其他不可枚举的属性。 对于更加复杂的(反)序列化使用场景,推荐为类添加一个(计算)方法 toJSON,或使用一个类似 serializr 的序列化库。

  1. const obj = mobx.observable({
  2. x: 1
  3. })
  4. const clone = mobx.toJS(obj)
  5. console.log(mobx.isObservableObject(obj)) // true
  6. console.log(mobx.isObservableObject(clone)) // false

配置

对你的 MobX 实例进行微调。

configure

用法:对正在使用的 MobX 实例进行全局行为设置。用它来改变 MobX 整体的行为方式。


用于集合的工具函数 {🚀}

这些工具函数可以让我们用同一个通用 API 对 observable 数组、对象和 Maps 进行处理。这一点在没有 Proxy 支持的环境中很有用。

values

{🚀} 用法values(array|object|Set|Map)

以数组形式返回集合中所有的值。

keys

{🚀} 用法keys(array|object|Set|Map)

以数组形式返回集合中所有的键或索引。

entries

{🚀} 用法entries(array|object|Set|Map)

以数组形式返回集合中每个条目的 [key, value] 对。

set

{🚀} 用法set(array|object|Map, key, value)

更新集合。

remove

{🚀} 用法remove(array|object|Map, key)

从集合中删除项目。

has

{🚀} 用法has(array|object|Map, key)

检查该集合中是否存在 key

get

{🚀} 用法get(array|object|Map, key)


使用键从集合中获取值。

用于检查的工具函数 {🚀}

如果你想检查 MobX 的内部状态或者想在 MobX 的基础上打造酷炫的工具,这些工具函数可能会派上用场。

isObservable

{🚀} 用法:isObservable(array|object|Set|Map)

检查该对象或集合是否已被 MobX 转化成 observable。

isObservableProp

{🚀} 用法:isObservableProp(object, propertyName)

检查该属性是否是 observable。

isObservableArray

{🚀} 用法:isObservableArray(array)

检查该值是否是一个 observable 数组。

isObservableObject

{🚀} 用法:isObservableObject(object)

检查该值是否是一个 observable 对象。

isObservableSet

{🚀} 用法:isObservableSet(set)

检查该值是否是一个 observable Set。

isObservableMap

{🚀} 用法:isObservableMap(map)

检查该值是否是一个 observable Map。

isBoxedObservable

{🚀} 用法:isBoxedObservable(value)

检查该值是否是一个用 observable.box 创建的 observable box。

isAction

{🚀} 用法:isAction(func)

检查该函数是否已被标记为 action

isComputed

{🚀} 用法:isComputed(boxedComputed)

检查该值是否是一个用 computed(() => expr) 创建的 box 计算值。

isComputedProp

{🚀} 用法:isComputedProp(object, propertyName)

检查该属性是否是一个计算属性。

trace

{🚀} 用法trace()trace(true) (enter debugger)trace(object, propertyName, enterDebugger?)

应在 observer、action 或计算值中使用。在所提供的 derivation 失效时打印日志,或者用 true 调用这个方法来设置调试器断点。

spy

{🚀} 用法spy(eventListener)

注册一个全局 spy 监听函数,该函数会监听所有在 MobX 内部发生的事件。

getDebugName

{🚀} 用法getDebugName(reaction|array|Set|Map)getDebugName(object|Map, propertyName)

为一个 observable 或 reaction 返回其(被生成出来的)友好的调试名称。

getDependencyTree

{🚀} 用法getDependencyTree(object, computedPropertyName)

返回一个树形结构,其中包含给定的 reaction 或计算值当前依赖的所有 observable。

getObserverTree

{🚀} 用法getObserverTree(array|Set|Map)getObserverTree(object|Map, propertyName)

返回一个树形结构,其中包含当前正在观察给定 observable 的所有 reactions 或计算值。


扩展 MobX {🚀}

在极少数情况下,你需要扩展 MobX 本身。

createAtom

{🚀} 用法createAtom(name, onBecomeObserved?, onBecomeUnobserved?)

创建你自己的 observable 数据结构并将其接入 MobX。所有 observable 数据类型内部都使用了该方法。Atom 暴露了两个 report 方法,用来在以下情况下对 MobX 进行通知:

  • reportObserved():该 atom 已经开始被观察,并且应被视为当前 derivation 的依赖所组成的树状结构的一部分。
  • reportChanged(): 该 atom 已经发生改变,并且所有依赖它的 derivations 都应失效。

getAtom

{🚀} 用法getAtom(thing, property?)

返回 observable 背后的 atom。

transaction

{🚀} 用法:transaction(worker: () => any)

Transaction 是底层 API。推荐改用 actionrunInAction

用于批量处理多个更新,直到该 transaction 结束时再通知所有 observer。跟 untracked 一样,transaction 会被 action 自动执行,所以通常情况下,使用 actions 比直接使用 transaction 更加合理。

它只接受一个没有形参的 worker 函数作为实参,并返回这个函数返回的任何值。请注意 transaction 是完全同步执行的并且可以被嵌套。正在等待的 reactions 只有当最外层的 transaction 完成之后才会被执行。

  1. import { observable, transaction, autorun } from "mobx"
  2. const numbers = observable([])
  3. autorun(() => console.log(numbers.length, "numbers!"))
  4. // Prints: '0 numbers!'
  5. transaction(() => {
  6. transaction(() => {
  7. numbers.push(1)
  8. numbers.push(2)
  9. })
  10. numbers.push(3)
  11. })
  12. // Prints: '3 numbers!'

untracked

{🚀} 用法:untracked(worker: () => any)

Untracked 是底层 API。推荐改用 reactionactionrunInAction

在不设置 observer 的情况下执行一段代码。跟 transaction 一样,untracked 会被 action 自动执行,所以通常情况下,使用 actions 比直接使用 untracked 更加合理。

  1. const person = observable({
  2. firstName: "Michel",
  3. lastName: "Weststrate"
  4. })
  5. autorun(() => {
  6. console.log(
  7. person.lastName,
  8. ",",
  9. // This untracked block will return the person's
  10. // firstName without establishing a dependency.
  11. untracked(() => person.firstName)
  12. )
  13. })
  14. // Prints: 'Weststrate, Michel'
  15. person.firstName = "G.K."
  16. // Doesn't print!
  17. person.lastName = "Chesterton"
  18. // Prints: 'Chesterton, G.K.'