在 MobX 中,使用 ES7 语法的 修饰器(Decorator) ,可以极大的简化组织代码
修饰器其实是对于一种函数形式的语法糖
@decorator
class A {}
// 等同于
class A {}
A = decorator(A) || A;
配置 ES6 以及 修饰器 ,最方便的当然是使用 babel 来编译 ES6 代码了,在 .babelrc 中配置:
{
"presets": [
"es2015",
"stage-1"
],
"plugins": ["transform-decorators-legacy"]
}
可观察状态(State)
@observable classProperty = value
@observable
接受任何类型的 js 值(原始类型、引用、纯对象、类实例、数组和、maps),observable 的属性值在其变化的时候 mobx 会自动追踪并作出响应。
当 value 是一个对象类型值的时候,它会默认克隆该对象并且把其中每个属性变为可观察的值,这里默认是深拷贝,也就是说其对象的后代属性都会变成可观察的,比如 @observable classProperty = { obj: { name: 'q' } }
,当 classProperty.obj.name
改变的时候,在 MobX 中也是可以观察到并响应的;
当然在这里可以加一些调节器来做一些配置:
- @observable.deep (默认)对对象进行深拷贝;
- @observable.shallow 它只对对象进行浅拷贝;
- @observable.ref 禁用对象的自动转化,只转化其引用;
这里需要注意的是,当定义好其 observable 的对象值后,对象中后来添加的值是不会变为可观察的,这时需要使用 extendObservable 来扩展对象:
const { observable, action, computed, autorun, extendObservable } = mobx;
class Store {
@observable oo = {
name: 1
}
};
const mstore = new Store();
extendObservable(mstore, {
oo: {
age: 0
}
});
var i = 1;
setInterval(() => {
mstore.oo.age = i++;
}, 2000);
autorun(() => {
console.log(mstore.oo.age);
});
计算属性值(Computed Values)
计算属性值实际上是一类衍生值,它是根据现有的状态或者其他值计算而来,原则上在计算属性中尽可能地不对当前状态做任何修改;
同时对于任何可以通过现有状态数据得到的值都应该通过计算属性获取。
语法为:@computed get computesValue [function]
;
运行观察(autorun)
在上面的例子中,当触发了可观察状态属性的改变后,其变化的监听则是在传入 autorun 函数中作出响应。
autorun 接受一个函数作为参数,在使用 autorun 的时候,该函数会被立即调用一次,之后当该函数中依赖的可观察状态属性(或者计算属性)发生变化的时候,该函数会被调用,注意,该函数的调用取决的函数中使用了哪些可观察状态属性(或者计算属性)。
autorun 中的函数就是用来操作 Reactions 的,当可观察状态属性的值发生改变的时候,可以在该函数中利用状态值来更新改变 UI 视图(记录日志、持久化),在 MobX 结合 React 的使用中,mobx-react 库则是封装了 autorun 用来在 store 中的可观察状态属性值发生改变的时候 rerender React 组件。
异步行为
action
包装/装饰器只会对当前运行的函数作出反应,而不会对当前运行函数所调用的函数(不包含在当前函数之内)作出反应! 这意味着如果 action 中存在 setTimeout
、promise 的 then
或 async
语句,并且在回调函数中某些状态改变了,那么这些回调函数也应该包装在 action
中。
runInAction(()=>{})