- MobX API参考
- 核心API
- 创建 observables
observable(value)@observable property = valueobservable.box(value)&observable.shallowBox(value)observable.object(value)&observable.shallowObject(value)observable.array(value)&observable.shallowArray(value)observable.map(value)&observable.shallowMap(value)extendObservable&extendShallowObservable- 调节器
- Computed values(计算值)
- Actions(动作)
- Reactions(反应) & Derivations(衍生)
observerautorunwhenautorunAsyncreactionexpronReactionError
- 创建 observables
- 实用工具
Provider(mobx-react包)inject(mobx-react包)toJSisObservableisObservableObject|Array|Map和isBoxedObservableisArrayLikeisActionisComputedcreateTransformerinterceptobserveuseStrict
- 开发工具
"mobx-react-devtools"包tracespywhyRunextras.getAtomextras.getDebugNameextras.getDependencyTreeextras.getObserverTreeextras.isSpyEnabledextras.spyReportextras.spyReportStartextras.spyReportEnd"mobx-react"开发钩子
- 内部函数
transactionuntrackedAtomReactionextras.allowStateChangesextras.resetGlobalState
MobX API参考
适用于 MobX 3或者更高版本。对于 MobX 2,旧文档依然可以在github找到。
核心API
MobX 中最重要的API。理解了observable、 computed、 reactions 和 actions的话,说明对于 Mobx 已经足够精通了,在你的应用中使用它吧!
创建 observables
observable(value)
用法:
observable(value)@observable classProperty = value
Observable 值可以是JS基本数据类型、引用类型、普通对象、类实例、数组和映射。observable(value) 是一个方便的重载函数,总是试图创建最佳匹配的 observable 类型。
你也可以直接创建所需的 observable 类型,请参见下文。
匹配类型应用了以下转换规则,但可以通过使用调节器进行微调。请参见下文。
- 如果 value 是ES6 Map的实例: 会返回一个新的 Observable Map。如果你不只关注某个特定entry的更改,而且对添加或删除其他entry时也做出反应的话,那么 Observable map 会非常有用。
- 如果 value 是数组,会返回一个 Observable Array。
- 如果 value 是没有原型的对象或它的原型是
Object.prototype,那么对象会被克隆并且所有的属性都会被转换成可观察的。参见 Observable Object。 - 如果 value 是有原型的对象,JavaSript原始数据类型或者函数,会返回一个 Boxed Observable。MobX 不会将一个有原型的对象自动转换成可观察的,因为这是它构造函数的职责。对于这些类型你需要在它的构造函数中使用
extendObservable或者在它的类定义中使用@observable。
乍看之下,这些规则可能看上去很复杂,但实际上实践当中你会发现他们是非常直观的。
一些建议:
- 要创建键是动态的对象时永远都使用 maps!对象上只有初始化时便存在的属性会转换成可观察的,尽管新添加的属性可以通过使用
extendObservable转换成可观察的。 - 要想使用
@observable装饰器,首先要确保 在你的编译器(babel 或者 typescript)中 装饰器是启用的。 - 默认情况下将一个数据结构转换成可观察的是有感染性的,这意味着
observable被自动应用于数据结构包含的任何值,或者将来会被该数据结构包含的值。这个行为可以通过使用 modifiers 或 shallow 来更改。
«observable» — «@observable»
@observable property = value
observable 也可以用作属性的装饰器。它需要启用装饰器而且它是 extendObservable(this, { property: value }) 的语法糖。
«详情»
observable.box(value) & observable.shallowBox(value)
创建一个 observable 的盒子,它用来存储value的 observable 引用。使用 get() 方法可以得到盒子中的当前value,而使用 set() 方法可以更新value。
这是所有其它 observable 创建的基础,但实际中你其实很少能使用到它。
通常盒子会自动地尝试把任何还不是 observable 的新值转换成 observable 。使用 shallowBox 会禁用这项行为。
«详情»
observable.object(value) & observable.shallowObject(value)
为提供的对象创建一个克隆并将其所有的属性转换成 observable 。
默认情况下这些属性中的任何值都会转换成 observable,但当使用 shallowObject 时只有属性会转换成 observable 引用,而值不会改变(这也适用于将来分配的任何值)。
«详情»
observable.array(value) & observable.shallowArray(value)
基于提供的值来创建一个新的 observable 数组。如果不想数组中的值转换成 observable 请使用 shallowArray。
«详情»
observable.map(value) & observable.shallowMap(value)
基于提供的值来创建一个新的 observable 映射。如果不想映射中的值转换成 observable 请使用 shallowMap。
当想创建动态的键集合并且需要能观察到键的添加和移除时,请使用 map。
注意只支持字符串键。
«详情»
extendObservable & extendShallowObservable
用法: extendObservable(target, ...propertyMaps)。对于 propertyMap 中的每个键值对,都会作为一个(新)的 observable 属性引入到 target 对象中。
还可以在构造函数中使用来引入 observable 属性,这样就不需要用装饰器了。
如果 propertyMap 的某个值是一个 getter 函数,那么会引入一个computed属性。
如果新的属性不应该具备感染性(即新分配的值不应该自动地转换成 observable)的话,请使用 extendShallowObservable。
注意 extendObservable 增强了现有的对象,不像 observable.object 是创建一个新对象。
«详情»
调节器
调节器可以作为装饰器或者组合 extendObservable 和 observable.object 使用,以改变特定属性的自动转换规则。
可用的调节器列表:
observable.deep: 所有 observable 都使用的默认的调节器。它可以把任何指定的、非原始数据类型的、非 observable 的值转换成 observable。observable.ref: 禁用自动的 observable 转换,只是创建一个 observable 引用。observable.shallow: 只能与集合组合使用。 将任何分配的集合转换为浅 observable (而不是深 observable)的集合。 换句话说, 集合中的值将不会自动变为 observable。computed: 创建一个衍生属性, 参见computedaction: 创建一个动作, 参见action
调节器可以作为装饰器使用:
class TaskStore {@observable.shallow tasks = []}
或者作为属性调节器组合 observable.object / observable.extendObservable 使用。
注意,调节器总是“附着”在属性上的。 因此,即使分配了新值,它们仍将保持有效。
const taskStore = observable({tasks: observable.shallow([])})
«详情»
Computed values(计算值)
用法:
computed(() => expression)computed(() => expression, (newValue) => void)computed(() => expression, options)@computed get classProperty() { return expression; }@computed.struct get classProperty() { return expression; }
创建计算值,expression 不应该有任何副作用而只是返回一个值。
如果任何 expression 中使用的 observable 发生改变,它都会自动地重新计算,但前提是计算值被某些 reaction 使用了。
«详情»
Actions(动作)
任何应用都有动作。动作是任何用来修改状态的东西。
使用MobX你可以在代码中显式地标记出动作所在的位置。
动作可以有助于更好的组织代码。
建议在任何更改 observable 或者有副作用的函数上使用动作。
结合开发者工具的话,动作还能提供非常有用的调试信息。
注意: 当启用严格模式时,需要强制使用 action,参见 useStrict。
«详情»
用法:
action(fn)action(name, fn)@action classMethod@action(name) classMethod@action boundClassMethod = (args) => { body }@action(name) boundClassMethod = (args) => { body }
对于一次性动作,可以使用 runInAction(name?, fn, scope?) , 它是 action(name, fn, scope)() 的语法糖.
Reactions(反应) & Derivations(衍生)
计算值 是自动响应状态变化的值。
反应 是自动响应状态变化的副作用。
反应可以确保当相关状态发生变化时指定的副作用(主要是 I/O)可以自动地执行,比如打印日志、网络请求、等等。
使用反应最常见的场景是 React 组件的 observer 装饰器(参见下文)。
observer
可以用作包裹 React 组件的高阶组件。
在组件的 render 函数中的任何已使用的 observable 发生变化时,组件都会自动重新渲染。
注意 observer 是由 "mobx-react" 包提供的,而不是 mobx 本身。
«详情»
用法:
observer(React.createClass({ ... }))observer((props, context) => ReactElement)observer(class MyComponent extends React.Component { ... })@observer class MyComponent extends React.Component { ... }
autorun
用法:autorun(debugname?, () => { sideEffect })。autorun 负责运行所提供的 sideEffect 并追踪在sideEffect运行期间访问过的 observable 的状态。
将来如果有其中一个已使用的 observable 发生变化,同样的sideEffect会再运行一遍。autorun 返回一个清理函数用来取消副作用。«详情»
when
用法: when(debugname?, () => condition, () => { sideEffect })。condition 表达式会自动响应任何它所使用的 observable。
一旦表达式返回的是真值,副作用函数便会立即调用,但只会调用一次。when 返回一个清理函数用来提早取消这一切。«详情»
autorunAsync
用法: autorunAsync(debugname?, () => { sideEffect }, delay)。类似于 autorun,但是sideEffect会延迟执行,并且根据给定的 delay 来进行函数去抖(debounce)。
«详情»
reaction
用法: reaction(debugname?, () => data, data => { sideEffect }, fireImmediately = false, delay = 0).reaction 是 autorun 的变种,在如何追踪 observable 方面给予了更细粒度的控制。
它接收两个函数,第一个是追踪并返回数据,该数据用作第二个函数,也就是副作用的输入。
与 ‘autorun’ 不同的是副作用起初不会运行,并且在执行副作用时访问的任何 observable 都不会被追踪。
和 autorunAsync 一样,副作用是可以进行函数去抖的。«详情»
expr
用法: expr(() => someExpression)。只是computed(() => someExpression).get() 的简写形式。expr 在一些极少数场景下用来优化另一个计算值函数或者 reaction 是有用的。
通常情况是将函数拆分成一些更小的计算值函数来达到同样的效果,这样做更简单,也更合理。
«详情»
onReactionError
用法: extras.onReactionError(handler: (error: any, derivation) => void)
此方法附加一个全局错误监听器,对于从 reaction 抛出的每个错误都会调用该错误监听器。
它可以用来监控或者测试。
实用工具
有一些工具函数可以使得 observable 或者 计算值用起来更方便。
更多实用工具可以在 mobx-utils 包中找到。
Provider (mobx-react 包)
可以用来使用 React 的context机制来传递 store 给子组件。参见mobx-react 文档。
inject (mobx-react 包)
相当于Provider 的高阶组件。可以用来从 React 的context中挑选 store 作为 prop 传递给目标组件。用法:
inject("store1", "store2")(observer(MyComponent))@inject("store1", "store2") @observer MyComponent@inject((stores, props, context) => props) @observer MyComponent@observer(["store1", "store2"]) MyComponentis a shorthand for the the@inject() @observercombo.
toJS
用法: toJS(observableDataStructure)。把 observable 数据结构转换成普通的 javascript 对象并忽略计算值。 «详情»
isObservable
用法: isObservable(thing, property?)。如果给定的thing,或者thing指定的property是 observable 的话,返回true。
适用于所有的 observable、计算值和 reaction 的清理函数。«详情»
isObservableObject|Array|Map 和 isBoxedObservable
用法: isObservableObject(thing), isObservableArray(thing), isObservableMap(thing), isBoxedObservable(thing)。 如果类型匹配的话返回true。
isArrayLike
用法: isArrayLike(thing)。如果给定的thing是 javascript 数组或者 observable (MobX的)数组的话,返回true。
这个方法更简便。
注意,observable 数组可以通过 .slice() 转变成 javascript 数组。
isAction
用法: isAction(func)。如果给定函数是用action 方法包裹的或者是用 @action 装饰的话,返回true。
isComputed
用法: isComputed(thing, property?)。如果给定的thing是计算值或者thing指定的property是计算值的话,返回true。
createTransformer
用法: createTransformer(transformation: A => B, onCleanup?): A = B。
可以用来创建将一个值转换为另一个可以反应和记忆的值的函数。
它的行为类似于计算值,可以用于一些高级模式,比如非常高效的数组映射,映射归并或者不是对象的一部分的计算值。
«详情»
intercept
用法: intercept(object, property?, interceptor).
这个 API 可以在应用 observable 的API之前,拦截更改。对于验证、标准化和取消等操作十分有用。
«详情»
observe
用法: observe(object, property?, listener, fireImmediately = false)
这是一个底层API,用来观察一个单个的 observable 值。
«详情»
useStrict
用法: useStrict(boolean)。
全局性 地启用/禁用严格模式。
在严格模式下,不允许在 action 外更改任何状态。
还可以参见 extras.allowStateChanges。
开发工具
如果你想在 MobX 的上层构建一些很酷的工具或者想检查 MobX 的内部状态的话,下列API可能会派上用场。
"mobx-react-devtools" 包
mobx-react-devtools 是个功能强大的包,它帮助你调查 React 组件的性能和依赖。
还有基于 spy 的强大的日志功能。«详情»
trace
用法:
trace(enterDebugger?)trace(Reaction object / ComputedValue object / disposer function, enterDebugger?)trace(object, computedValuePropertyName, enterDebugger?)
trace 是一个可以在计算值或 reaction 中使用的小工具。
如果启用了它,那么当值被无效时,它将开始记录,以及为什么。
如果 enterDebugger 设置为 true ,并且启用开发者工具的话,JavaScript 引擎会在触发时在此进行断点调试。
«trace»
spy
用法: spy(listener).
注册全局侦查监听器可以监听所有 MobX 中发生的事件。
它类似于将一个 observe 监听器一次性附加到所有的 observables 上,而且还负责正在运行的动作和计算的通知。
用于 mobx-react-devtools 。
«详情»
whyRun
用法:
whyRun()whyRun(Reaction object / ComputedValue object / disposer function)whyRun(object, "computed property name")
whyRun 建议废弃,推荐使用 trace
whyRun 是个可以在computed或 reaction(autorun、 reaction 或 使用了 observer 的 React 组件的 render 方法)中使用的小功能,它可以打印出 衍生(derivation) 正在运行的原因以及在哪种情况下它会再次运行。
这应该有助于更深入地了解 MobX 运作的时机和原因,并防止一些初学者的错误。
extras.getAtom
用法: getAtom(thing, property?).
返回给定的 observable 对象、属性、reaction 等的背后作用的Atom。
extras.getDebugName
用法: getDebugName(thing, property?)
返回 observable 对象、属性、reaction等(生成的)易读的调试名称。用于 mobx-react-devtools 的示例。
extras.getDependencyTree
用法: getDependencyTree(thing, property?).
返回给定的 reaction / 计算 当前依赖的所有 observable 的树型结构。
extras.getObserverTree
用法: getObserverTree(thing, property?).
返回正在观察给定的 observable 的所有 reaction / 计算的树型结构。
extras.isSpyEnabled
用法: isSpyEnabled(). 如果至少有一个 spy 是活动的话,返回true。
extras.spyReport
用法: spyReport({ type: "your type", «details» data})。 发射自定义spy事件。
extras.spyReportStart
用法: spyReportStart({ type: "your type", «details» data})。 发射自定义spy事件。将启动一个新的嵌套spy事件组,该事件组应该使用 spyReportEnd() 关闭。
extras.spyReportEnd
用法: spyReportEnd()。关闭由 extras.spyReportStart 开启的当前spy的事件组。
"mobx-react" 开发钩子
mobx-react 包提供了以下几个供 mobx-react-devtools 使用的附加API:
trackComponents(): 启用追踪功能,追踪使用了observer的 React 组件renderReporter.on(callback): 使用observer的 React 组件每次渲染都会调用callback,并附带相关的时间信息等等componentByNodeRegistery: 使用ES6 WeakMap 将 DOMNode 映射到使用observer的 React 组件实例
内部函数
以下方法都在 MobX 内部使用,在极少数情况下可能会派上用场。 但是通常 MobX 提供了更多的声明性替代方法来解决同样的问题。如果你尝试扩展 MobX 的话,它们可能会派上用场。
transaction
用法: transaction(() => { block }).
已废弃,使用 action 或者 runInAction 替代。
低等级API,用于批量处理状态更改。
在block中进行的状态更改在block结束前不会导致任何计算或 reaction 的运行。
尽管如此,(不管何时)检查transaction中computed值,返回的值仍然是一致的。
建议使用 action来替代,它会在内部使用 transaction。
«详情»
untracked
用法: untracked(() => { block }).
低等级API,在 reactions 和 compuations 内部可能会有用处。
在 block 中访问任何 observable 都不会导致 reaction / compuation 自动重新计算。同样,
建议使用 action来替代,它会在内部使用 untracked。
«详情»
Atom
实用程序类,可用于创建你自己的 observable 数据结构,并将它们连接到 MobX。
在所有 observable 数据类型的内部使用。
«详情»
Reaction
实用程序类,可用于创建自己的 reaction ,并将它们连接到 MobX。
在 autorun, reaction (函数)等内部使用。
«详情»
extras.allowStateChanges
用法: allowStateChanges(allowStateChanges, () => { block }).
可以用于 允许/禁止 某个函数中的状态变化。
在 action 内部使用以允许更改,在 computed 和 observer 内部使用以禁止状态更改。
extras.resetGlobalState
用法: resetGlobalState().
重置 MobX 内部全局状态。默认情况下 MobX 使用快速失败(fail fast)机制, 如果在computation或 reaction 内发生异常,MobX会拒绝再次运行它们。
此函数将 MobX 重置为归零状态。 现有的 spy 监听器和严格模式下的当前值将被保留。
