MobX API 参考
用 {🚀} 标记的函数是进阶部分,通常不需要使用。 请考虑下载我们的速查表,它用一页篇幅解释了所有重要的 API:
核心 API
这些是 MobX 中最重要的 API。
理解
observable
,computed
,reaction
和action
就足够你掌握 MobX 并在你的应用中使用它了!
创建 observables
把事物变得可观察。
makeObservable
用法:makeObservable(target, annotations?, options?)
属性、整个对象、数组、Maps 和 Sets 都可以变得可观察。
makeAutoObservable
用法:makeAutoObservable(target, overrides?, options?)
自动把属性、对象、数组、Maps 和 Sets 变得可观察。
extendObservable
{🚀} 用法:extendObservable(target, properties, overrides?, options?)
可以用来在 target
对象上引入新属性并立即把它们全都变得可观察。基本上就是 Object.assign(target, properties); makeAutoObservable(target, overrides, options);
的简写。但它不会变动 target
上已有的属性。
老式的构造器函数可以很好跟 extendObservable
结合起来使用:
function Person(firstName, lastName) {
extendObservable(this, { firstName, lastName });
}
const person = new Person('Michel', 'Weststrate');
使用 extendObservable
在一个对象实例化之后再为其添加可观察字段也是可以的,但要注意,以这种方式添加可观察属性这一行为本身并不能被观察到。
observable
用法:observable(source, overrides?, options?)
或 observable
(注解)
克隆一个对象并使其可观察。source
可以是一个普通的对象、数组、Map 或 Set。默认情况下, observable
会被递归调用。如果遇到的值中有一个是对象或数组,那么那个值也会被传入 observable
。
observable.object
{🚀} 用法:observable.object(source, overrides?, options?)
observable(source, overrides?, options?)
的别名。创建一个被传入对象的副本并使它的所有属性可观察。
observable.array
{🚀} 用法:observable.array(initialValues?, options?)
根据被传入的 initialValues
创建一个新的可观察数组。
如果要把可观察数组转化回普通的数组,就请使用 .slice()
方法,或者参阅 toJS 进行递归转化。
除了语言中内置的所有数组方法之外,可观察数组中还有以下好东西可用:
clear()
删除数组中所有现存的元素。replace(newItems)
用新元素替换数组中所有现存的元素。remove(value)
从数组中删除一个值为value
的元素,在找到并删除该元素后返回true
。
如果数组中的值不能被自动转化为 observable,则可使用 { deep: false }
选项对该数组进行浅转化。
observable.map
{🚀} 用法:observable.map(initialMap?, options?)
根据被传入的 initialMap
创建一个新的可观察的 ES6 Map。
如果你不仅想对特定值的改变作出反应,还想对其添加和删除做出反应的话,那么它们就会变得非常有用。
如果你没有启用代理,那么推荐你使用创建可观察 Maps 的方式来创建动态键控集合。
除了语言内置的所有 Map 方法之外,可观察 Maps 中还有以下好东西可用:
toJSON()
返回该 Map 的浅层普通对象表示(使用 toJS 进行深拷贝)。merge(values)
将被传入的values
(普通的对象、数组或以字符串为键的 ES6 Map )的所有条目复制到该 Map 中。replace(values)
用被传入的values
替换该 Map 的全部内容。
如果 Map 中的值不能被自动转化为 observable,则可使用 { deep: false }
选项对该 Map 进行浅转化。
observable.set
{🚀} 用法:observable.set(initialSet?, options?)
根据提供的 initialSet
创建一个新的可观察的 ES6 Set。每当你想创建一个动态集合,并需要观察值的添加和删除,但每个值在整个集合中只能出现一次时,就可以使用它。
如果 Set 中的值不能被自动转化为 observable,则可使用 { deep: false }
选项对该 Set 进行浅转化。
observable.ref
用法:observable.ref
(注解)
和 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 中的所有原始值都是不可变的,所以它们当然也都是不可观察的。 这一点通常没什么问题,因为 MobX 可以使包含该值的属性变成 observable。 在少数情况下,如果能有独立于对象的可观察原始值的话会很方便。 对于这种情况,可以创建一个可观察的box来管理这种原始值。
observable.box(value)
接受任意值并将其存储在一个 box 中。当前值可以通过 .get()
访问到,并使用 .set(newValue)
进行更新。
import { observable, autorun } from 'mobx';
const cityName = observable.box('Vienna');
autorun(() => {
console.log(cityName.get());
});
// Prints: 'Vienna'
cityName.set('Amsterdam');
// Prints: 'Amsterdam'
如果 box 中的值不能被自动转化为 observable,则可使用 { deep: false }
对该 box 进行浅转化。
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 包装所进行的类型上的更正。它在运行时会直接返回被输入的值。
计算值
计算值可以用来从其他 observables 中派生出数据。
computed
用法:computed(fn, options?)
或 computed(options?)
(注解)
创建一个从其他 observables 中派生出来的可观察值。但只要底层 observables 不变,就这个值就不会被重新计算。
与 React 的整合
来自 mobx-react
或 mobx-react-lite
包。
observer
用法:observer(component)
可以用来使一个函数式或基于类的 React 组件在 observables 发生改变时重新渲染的高阶组件。
Observer
用法:<Observer>{() => rendering}</Observer>
渲染被传入的 render 函数,并在 render 函数使用的 observables 之一发生改变时将其重新渲染。
useLocalObservable
用法:useLocalObservable(() => source, annotations?)
使用 makeObservable
创建一个新的可观察对象,并在组件的整个生命周期内将其保留在组件中。
Reactions
Reactions 用来对自动发生的副作用进行建模。
autorun
用法:autorun(() => effect, options?)
每当其观察的任意一个值发生改变时重新执行一个函数。
reaction
用法:reaction(() => data, data => effect, options?)
当任何一个被选中的数据发生改变时重新执行一个副作用。
when
用法:when(() => condition, () => effect, options?)
或 await when(() => condition, options?)
在一个可观察条件变为真时将一个副作用执行一次。
实用程序
这些实用程序可能会使得对可观察对象或计算值的处理更加方便。你在 mobx-utils 包中也可以找到更复杂的实用程序。
onReactionError
{🚀} 用法:onReactionError(handler: (error: any, derivation) => void)
绑定一个全局错误监听函数,每当一个 reaction 抛出错误时都会调用这个监听函数。可以用于监控或测试。
intercept
{🚀} 用法:intercept(propertyName|array|object|Set|Map, listener)
在变更被应用到一个可观察的 API 之前对其进行拦截。返回一个阻止拦截的处置函数。
observe
{🚀} 用法:observe(propertyName|array|object|Set|Map, listener)
可用于观察单个可观察值的底层 API。返回一个阻止拦截的处置函数。
onBecomeObserved
{🚀} 用法:onBecomeObserved(observable, property?, listener: () => void)
在某个值开始被监控时使用的钩子函数。
onBecomeUnobserved
{🚀} 用法:onBecomeUnobserved(observable, property?, listener: () => void)
在某个值停止被监控时使用的钩子函数。
toJS
用法:toJS(value)
将一个可观察对象递归转化为一种 JavaScript 数据结构。支持可观察数组、对象、Maps 和原始值。
对于更加复杂的(反)序列化使用场景,建议为类添加一个(计算)方法 toJSON
,或者使用一个类似 serializr 的序列化库。
const obj = mobx.observable({
x: 1
});
const clone = mobx.toJS(obj);
console.log(mobx.isObservableObject(obj)); // true
console.log(mobx.isObservableObject(clone)); // false
配置
对你的 MobX 实例进行微调。
configure
用法:对正在使用的 MobX 实例进行全局行为设置。用它来改变 MobX 整体的行为方式。
用于集合的实用程序 {🚀}
这些实用程序可以让我们用同一个通用 API 对可观察数组、对象和 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)
这个属性是不是可观察的?
isObservableArray
{🚀} 用法:isObservableArray(array)
这个值是不是一个可观察数组?
isObservableObject
{🚀} 用法:isObservableObject(object)
这个值是不是一个可观察对象?
isObservableSet
{🚀} 用法:isObservableSet(set)
这个值是不是一个可观察 Set?
isObservableMap
{🚀} 用法:isObservableMap(map)
这个值是不是一个可观察 Map?
isBoxedObservable
{🚀} 用法:isBoxedObservable(value)
这个值是不是一个用 observable.box
创建的可观察 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 或计算值中使用。会当值无效时打印日志,否则如果用 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)
返回一个树形结构,该树形结构包含正在观察所有 reactions 或计算值。
Extending MobX {🚀}
In the rare case you want to extend MobX itself.
createAtom
{🚀} 用法:createAtom(name, onBecomeObserved?, onBecomeUnobserved?)
Creates your own observable data structure and hooks it up to MobX. Used internally by all observable data types. Atom exposes two report methods to notify MobX with when:
reportObserved()
: the atom has become observed, and should be considered part of the dependency tree of the current derivation.reportChanged()
: the atom has changed, and all derivations depending on it should be invalidated.
getAtom
{🚀} 用法:getAtom(thing, property?)
Returns the backing atom.
transaction
{🚀} 用法:transaction(worker: () => any)
Transaction is a low-level API. It is recommended to use action
或runInAction
instead.
Used to batch a bunch of updates without notifying any observers until the end of the transaction. Like untracked
, it is automatically applied by action
, so usually it makes more sense to use actions than to use transaction
directly.
It takes a single, parameterless worker
function as an argument, and returns any value that was returned by it.
Note that transaction
runs completely synchronously and can be nested. Only after completing the outermost transaction
, the pending reactions will be run.
import { observable, transaction, autorun } from 'mobx';
const numbers = observable([]);
autorun(() => console.log(numbers.length, 'numbers!'));
// Prints: '0 numbers!'
transaction(() => {
transaction(() => {
numbers.push(1);
numbers.push(2);
});
numbers.push(3);
});
// Prints: '3 numbers!'
untracked
{🚀} 用法:untracked(worker: () => any)
Untracked is a low-level API. It is recommended to use reaction
, action
或runInAction
instead.
Runs a piece of code without establishing observers. Like transaction
, untracked
is automatically applied by action
, so usually it makes more sense to use actions than to use untracked
directly.
const person = observable({
firstName: 'Michel',
lastName: 'Weststrate'
});
autorun(() => {
console.log(
person.lastName,
',',
// This untracked block will return the person's
// firstName without establishing a dependency.
untracked(() => person.firstName)
);
});
// Prints: 'Weststrate, Michel'
person.firstName = 'G.K.';
// Doesn't print!
person.lastName = 'Chesterton';
// Prints: 'Chesterton, G.K.'