Mobx 原理

原理

现象说明

mobx 会对对象做响应式代理:

  • 代理以后的对象属性分为了 get 和 set,并且实现变成了 this[$mobx].getObservablePropValue 和 setObservablePropValue。
  • 代理以后的方法都变成了 executeAction,执行方法会 dispatch 一个 acition。

img

如何实现响应式代理?

跟踪 makeAutoObservable 的源码会发现 mobx 创建了一个 ObservableObjectAdministration 的对象放到了 $mobx 属性上。

img

$mobx 属性是用 Symbol 声明了一个私有属性 mobx administration。还用 Symbol 声明了一个私有属性。mobx-keys 来放所有做了代理的属性和方法名。

ObservableObjectAdministration

看下它的定义:

img

可以看到它有 values 属性记录每个 key 的依赖。

还有 getObservableValue 和 setObservableValue 来获取和设置某个 key 的值。这两个方法就是被代理后的属性的 get set 最终调用的方法:

img

总结

创建对象的时候 mobx 会添加一个 Symbol(mobx administrator) 属性,来保存 ObservableObjectAdministration 对象,它是用来记录属性的所有依赖,对属性的 get 和 set 都会被代理到这个 ObservableObjectAdministration 的 getXxx 和 setXxx 方法上。

可以看到 values 里保存了唯一一个属性和它的所有依赖。

img

对对象做响应式代理的流程:

img

如何收集依赖?

我们用 observer 包裹了组件,它是一个高阶组件,对组件做一层代理,返回新的组件:

img

在这层代理里面,创建了 Reaction 对象,也就是收到更新的通知之后怎么做出反应,在回调函数里用 setState([]) 的方式实现了强制更新。

img

并且,这层高阶组件的代理里会把当前 Reaction 设置到全局,这样后面做 get 的依赖收集的时候就能拿到对应的 Reaction 了。

在后面修改响应式对象的状态属性的时候,会触发依赖,然后实现组件的更新:

img

总结

mobx 的响应式原理:mobx 会在对象上添加一个 Symbol($mobx) 的隐藏属性,用来放 ObservableObjectAdministration 对象,它是用于管理属性和它的依赖的,在 get 的 时候收集依赖,然后 set 的时候就可以通知所有收集到的依赖(Reaction)做更新。

img

参考文章

MobX 是怎么实现的?