MobX API 参考
用 {🚀} 标记的函数是进阶部分,通常不需要使用。 请考虑下载我们的小抄,它用一页纸解释了所有重要的 API:
核心 API
这些是 MobX 中最重要的 API。
理解
observable
,computed
,reaction
和action
就足够你掌握 MobX 并在你的应用中使用它了!
创建 observables
把事物变得可观察。
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
结合使用:
function Person(firstName, lastName) {
extendObservable(this, { firstName, lastName });
}
const person = new Person("Michel", "Weststrate");
在一个对象实例化之后使用 extendObservable
在该对象上添加可观察字段也是可以的,但要注意,以这种方式添加可观察属性这一行为本身并不能被观察到。
observable
用法: observable(source, overrides?, options?)
或 observable
(annotation)
克隆一个对象并将其转为 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
创建一个新的可观察的数组。
如果要把可观察的数组转化回普通的数组,就请使用 .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 )的所有条目复制到该地图中。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
(annotation)
和 observable
注解类似,但只会追踪重新赋值。所赋的值本身并不会被自动转化为 observable 。比如你可以在想要在一个可观察字段中储存不可变数据时使用它。
observable.shallow
用法: observable.shallow
(annotation)
和 observable.ref
注解类似,但它是用于集合的。所赋的所有集合都会被转为 observable ,但是集合本身的内容不会变为 observable 。
observable.struct
{🚀} 用法: observable.struct
(annotation)
除了忽略所有结构上等于当前值的所赋的值之外,其他方面和 observable
注解类似。
observable.deep
{🚀} 用法: observable.deep
(annotation)
observable
注解的别名。
observable.box
{🚀} 用法: observable.box(value, options?)
JavaScript 中的所有原始值都是不可变的,因而它们当然也都是不可观察的。 这一点通常没问题,因为 MobX 可以使包含该值的 属性 变成 observable 。 在少数情况下,如果能有一个不属于对象的可观察的 原始值 就会很方便。 对于这种情况,可以创建一个可观察的 box 来管理此类 primitive 。
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'
{ deep: false }
对该 box 进行浅转化。
如果 box 中的值不能被自动转化为 observable ,则可使用 Actions
An action is any piece of code that modifies the state.
action
用法: action(fn)
or action
(annotation)
Use on functions that intend to modify the state.
runInAction
{🚀} 用法: runInAction(fn)
Create a one-time action that is immediately invoked.
flow
用法: flow(fn)
or flow
(annotation)
MobX friendly replacement for async
/ await
that supports cancellation.
flowResult
用法: flowResult(flowFunctionResult)
For TypeScript users only. Utility that casts the output of the generator to a promise.
This is just a type-wise correction for the promise wrapping done by flow
. At runtime it directly returns the inputted value.
Computeds
Computed values can be used to derive information from other observables.
computed
用法: computed(fn, options?)
or computed(options?)
(annotation)
Creates an observable value that is derived from other observables, but won't be recomputed unless one of the underlying observables changes.
React integration
From the mobx-react
/ mobx-react-lite
packages.
observer
用法: observer(component)
A higher order component you can use to make a functional or class based React component re-render when observables change.
Observer
用法: <Observer>{() => rendering}</Observer>
Renders the given render function, and automatically re-renders it once one of the observables used in the render function changes.
useLocalObservable
用法: useLocalObservable(() => source, annotations?)
Creates a new observable object using makeObservable
, and keeps it around in the component for the entire life-cycle of the component.
Reactions
The goal of reactions is to model side effects that happen automatically.
autorun
用法: autorun(() => effect, options?)
Reruns a function every time anything it observes changes.
reaction
用法: reaction(() => data, data => effect, options?)
Reruns a side effect when any selected data changes.
when
用法: when(() => condition, () => effect, options?)
or await when(() => condition, options?)
Executes a side effect once when a observable condition becomes true.
Utilities
Utilities that might make working with observable objects or computed values more convenient. Less trivial utilities can also be found in the mobx-utils package.
onReactionError
{🚀} 用法: onReactionError(handler: (error: any, derivation) => void)
Attaches a global error listener, which is invoked for every error that is thrown from a reaction. This can be used for monitoring or test purposes.
intercept
{🚀} 用法: intercept(propertyName|array|object|Set|Map, listener)
Intercepts changes before they are applied to an observable API. Returns a disposer function that stops the interception.
observe
{🚀} 用法: observe(propertyName|array|object|Set|Map, listener)
Low-level API that can be used to observe a single observable value. Returns a disposer function that stops the interception.
onBecomeObserved
{🚀} 用法: onBecomeObserved(observable, property?, listener: () => void)
Hook for when something becomes observed.
onBecomeUnobserved
{🚀} 用法: onBecomeUnobserved(observable, property?, listener: () => void)
Hook for when something stops being observed.
toJS
用法: toJS(value)
Recursively converts an observable object to a JavaScript structure. Supports observable arrays, objects, Maps and primitives.
Computed values and other non-enumerable properties won't be part of the result.
For more complex (de)serialization scenarios, it is recommended to give classes a (computed) toJSON
method, or use a serialization library like serializr.
const obj = mobx.observable({
x: 1
})
const clone = mobx.toJS(obj)
console.log(mobx.isObservableObject(obj)) // true
console.log(mobx.isObservableObject(clone)) // false
Configuration
Fine-tuning your MobX instance.
configure
用法: sets global behavior settings on the active MobX instance. Use it to change how MobX behaves as a whole.
Collection utilities {🚀}
They enable manipulating observable arrays, objects and Maps with the same generic API. This can be useful in environments without Proxy
support, but is otherwise typically not needed.
values
{🚀} 用法: values(array|object|Set|Map)
Returns all values in the collection as an array.
keys
{🚀} 用法: keys(array|object|Set|Map)
Returns all keys / indices in the collection as an array.
entries
{🚀} 用法: entries(array|object|Set|Map)
Returns a [key, value]
pair of every entry in the collection as an array.
set
{🚀} 用法: set(array|object|Map, key, value)
Updates the collection.
remove
{🚀} 用法: remove(array|object|Map, key)
Removes item from the collection.
has
{🚀} 用法: has(array|object|Map, key)
Checks for membership in the collection.
get
{🚀} 用法: get(array|object|Map, key)
Gets value from the collection with key.
Introspection utilities {🚀}
Utilities that might come in handy if you want to inspect the internal state of MobX, or want to build cool tools on top of MobX.
isObservable
{🚀} 用法: isObservable(array|object|Set|Map)
Is the object / collection made observable by MobX?
isObservableProp
{🚀} 用法: isObservableProp(object, propertyName)
Is the property observable?
isObservableArray
{🚀} 用法: isObservableArray(array)
Is the value an observable array?
isObservableObject
{🚀} 用法: isObservableObject(object)
Is the value an observable object?
isObservableSet
{🚀} 用法: isObservableSet(set)
Is the value an observable Set?
isObservableMap
{🚀} 用法: isObservableMap(map)
Is the value an observable Map?
isBoxedObservable
{🚀} 用法: isBoxedObservable(value)
Is the value an observable box, created using observable.box
?
isAction
{🚀} 用法: isAction(func)
Is the function marked as an action
?
isComputed
{🚀} 用法: isComputed(boxedComputed)
Is this a boxed computed value, created using computed(() => expr)
?
isComputedProp
{🚀} 用法: isComputedProp(object, propertyName)
Is this a computed property?
trace
{🚀} 用法: trace()
, trace(true)
(enter debugger) or trace(object, propertyName, enterDebugger?)
Should be used inside an observer, reaction or computed value. Logs when the value is invalidated, or sets the debugger breakpoint if called with true.
spy
{🚀} 用法: spy(eventListener)
Registers a global spy listener that listens to all events that happen in MobX.
getDebugName
{🚀} 用法: getDebugName(reaction|array|Set|Map)
or getDebugName(object|Map, propertyName)
Returns the (generated) friendly debug name for an observable or reaction.
getDependencyTree
{🚀} 用法: getDependencyTree(object, computedPropertyName)
Returns a tree structure with all observables the given reaction / computation currently depends upon.
getObserverTree
{🚀} 用法: getObserverTree(array|Set|Map)
or getObserverTree(object|Map, propertyName)
Returns a tree structure with all reactions / computations that are observing the given observable.
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
or 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
or 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.'