MobX 4
原理
参考:zhuanlan.zhihu.com/p/25585910
Mobx 最关键的函数在于 autoRun
const obj = observable({
a: 1,
b: 2
})
autoRun里引用到了某个监听属性时(() => {
console.log(obj.a)
})
obj.b = 3 // 什么都没有发生
obj.a = 2 // observe 函数的回调触发了,控制台输出:2
- 当autoRun里引用到了某个监听属性时,就会与这个属性挂钩,当这个属性发生改变时,就会执行autoRun里面的回调函数
- 通过使用 autoRun 实现 mobx-react:通过@observer的修饰器,在组件将外面包上autoRun,这样当组件中使用了哪些监听属性,就会与autoRun,当某个监听属性发生改变时,就会触发autoRun,直接重新render
Mobx一些api
-
作出响应
- observable
import { observable, action } from 'mobx'; // observable可以定义一些被观察的属性 // action可以定义一些具有副作用的函数,比如改变observable的值store.js
import { observable, action } from 'mobx'; class store { @observable count = 0; @action addCount = () => { this.count ++ } } export default new store()也可以
import { observable, action } from 'mobx'; class store { @observable count = 0; @action addCount = () => { this.count ++ } } export default new store()一般第一种用的更多
-
computed 计算属性,当observable的属性修改后,才会重新计算
-
autorun autorun用来处理副作用,当observable的值发生变化是,就会触发observable
observable(() => console.log(this.count)) -
改变 observables
-
action
-
异步action:bound、flow
mobx.configure({ enforceActions: true }) // 不允许在动作之外进行状态修改 class Store { @observable count = 0; @action fetchProjects() { setTimeout(() => { this.count ++ }, 0); } }上面的this.count ++会报错,因为不是在@action的函数中修改@observable的变量
解决方法
- 可以把赋值的操作用bound绑定,写在外面:
mobx.configure({ enforceActions: true }) // 不允许在动作之外进行状态修改 class Store { @observable count = 0; @action fetchProjects() { setTimeout(() => { this.addCount(1) }, 0); } @action.bound addCount(num) { this.count += num } }尽管这很整洁清楚,但异步流程复杂后可能会略显啰嗦
- 在回调函数外面使用
action包装
mobx.configure({ enforceActions: true }) // 不允许在动作之外进行状态修改 class Store { @observable count = 0; @action fetchProjects() { setTimeout( action('随便一个命名', () => { this.count }) , 0); } @action fetchProjectsTwo() { setTimeout(() => { runInAction(() => this.count++) }, 0); } }runInAction是action的语法糖
- async / await
词法上它们看起来是同步函数,它给人的印象是 @action 应用于整个函数。 但事实并非若此,因为 async / await 只是围绕基于 promise 过程的语法糖。 结果是 @action 仅应用于代码块,直到第一个 await 所以在
async / await中,第一个await后面的,必须使用异步action@action async fetchProjects() { const { data } = await fetchGithubProjectsSomehow() // 一个获取接口数据的方法 runInAction(() => this.count = data.count) }- flow
fetchProjects = flow(function * () { // <- 注意*号,这是生成器函数! const { data } = yield fetchGithubProjectsSomehow() // 用yield代替await runInAction(() => this.count = data.count) })
-
-
工具函数
-
toJS 递归地将一个(observable)对象转换为 javascript 结构
-
extendObservable
extendObservable(storeName, { age: 353 }); -