原理
现象说明
mobx 会对对象做响应式代理:
- 代理以后的对象属性分为了 get 和 set,并且实现变成了 this[$mobx].getObservablePropValue 和 setObservablePropValue。
- 代理以后的方法都变成了 executeAction,执行方法会 dispatch 一个 acition。
如何实现响应式代理?
跟踪 makeAutoObservable 的源码会发现 mobx 创建了一个 ObservableObjectAdministration 的对象放到了 $mobx 属性上。
$mobx 属性是用 Symbol 声明了一个私有属性 mobx administration。还用 Symbol 声明了一个私有属性。mobx-keys 来放所有做了代理的属性和方法名。
ObservableObjectAdministration
看下它的定义:
可以看到它有 values 属性记录每个 key 的依赖。
还有 getObservableValue 和 setObservableValue 来获取和设置某个 key 的值。这两个方法就是被代理后的属性的 get set 最终调用的方法:
总结
创建对象的时候 mobx 会添加一个 Symbol(mobx administrator) 属性,来保存 ObservableObjectAdministration 对象,它是用来记录属性的所有依赖,对属性的 get 和 set 都会被代理到这个 ObservableObjectAdministration 的 getXxx 和 setXxx 方法上。
可以看到 values 里保存了唯一一个属性和它的所有依赖。
对对象做响应式代理的流程:
如何收集依赖?
我们用 observer 包裹了组件,它是一个高阶组件,对组件做一层代理,返回新的组件:
在这层代理里面,创建了 Reaction 对象,也就是收到更新的通知之后怎么做出反应,在回调函数里用 setState([]) 的方式实现了强制更新。
并且,这层高阶组件的代理里会把当前 Reaction 设置到全局,这样后面做 get 的依赖收集的时候就能拿到对应的 Reaction 了。
在后面修改响应式对象的状态属性的时候,会触发依赖,然后实现组件的更新:
总结
mobx 的响应式原理:mobx 会在对象上添加一个 Symbol($mobx) 的隐藏属性,用来放 ObservableObjectAdministration 对象,它是用于管理属性和它的依赖的,在 get 的 时候收集依赖,然后 set 的时候就可以通知所有收集到的依赖(Reaction)做更新。