MobX 运行机制

345 阅读2分钟

首先理解MobX的一些概念

1 状态(State)

在中文文档中,解释State为:驱动应用的数据。可以理解为组件中的各种数据。

2 衍生(Derivations)

2.1 计算值(Computed values)

使用纯函数,根据其他的可观察State计算结果。

//例1 
 @observable name ='';
 @computed get title() {
    return this.name;
  }
  //这个例子中,title依据可观察状态name的变化而变化

2.2 反应(Reactions)

跟计算值相似,都是依赖于其他可观测状态的变化得到执行结果。不同的是,计算值得到的是新值,但反应会产生副作用,我理解的反应就是根据可观测的状态来执行某些操作,但不会改变状态。例如日志记录、请求发送、UI渲染等。

//例2
  reaction(
      () => this.props.initSelectedStructures,
      (data) => {
        this.props.uiStore.selectedStructures = data;
      }
    );
    //反应不产生新的数据

计算值和反应统称为衍生

2.3 autorun

与Reaction相似的是autorun, 当使用 autorun 时,所提供的函数总是立即被触发一次,然后每次它的依赖关系改变时会再次被触发。对于两者我的理解是reaction有一个固定的观察对象,而autorun是只要函数中的可观测状态发生改变,都会触发执行。另外autorun总是会立即执行一次,而reaction只有观察的变量发生变化才会执行函数。

//例3
autorun(() => {
      const {workingMenu} = portalStore;
      if (workingMenu && workingMenu.code) {
        (portalStore.currentAppMenus || []).forEach((item) => {
          if (item.code === workingMenu.code || (item.children || []).some(({code}) => workingMenu.code === code)) {
            uiStore.setOpenKeys(item.id);
          }
        });
      }
    });

与autorun相比,computed(function) 创建的函数只有当它有自己的观察者时才会重新计算,并且得到的是一个新值。

中文文档中提到使用这两者的黄金法则,如果你有一个函数应该自动运行,但不会产生一个新的值,请使用autorun。 其余情况都应该使用 computed

3 动作(Action)

修改状态的行为要在Action中执行。

4 创建响应式组件(@observer)

MobX中文文档提到,使用observer可以讲React组件转化为响应式组件,实际上是用 mobx.autorun 包装了组件的 render 函数,以确保任何组件渲染中使用的数据变化时都可以强制刷新组件。

//例4
@observer
class App extends React.Component {
  render() {
    // ...
  }
}

MobX到底是怎么工作的?

在例4中,@observer是一种新的语法,叫做“装饰器”,表示对整个类的行为进行修改,即将App类作为参数传入observer函数。这里的意思是,整个App类都是一个“观察者”,观察store的变化,只要一有变化,立刻重新渲染(mobx.autorun),从而实现了状态更新,页面更新的效果。

传送门 中文文档