原文地址:mobx-react
文本是 mobx 源码解读系列 第五篇
本系列文章全部采用 mobx 较新版本:v5.13.0
技术前提
在阅读之前,希望你对以下技术有所了解或实践,不然可能会影响你对本文的理解
准备
一、目的
-
本文是
mobx 源码解读系列
的最后一篇,短短的五篇文章,对整个mobx
只能讲了个大概,源码爱好者们请自行深挖宝藏 -
最后一篇讲
mobx-react
,自从react
推出hooks
之后,那连接mobx
和react
不要太简单 -
mobx-react
6 版本配合了 mobx-react-lite 来处理function component
二、提要
-
上篇讲
autorun
如何向reaction
传参埋了个坑(详见:上篇),现在来填填 -
其实最直接的回答就是:
view
函数执行的结果,其他地方(库)还要使用呀
上源码
一、对 mobx 作出响应:observer
先从 mobx-react-lite 出发
- 函数组件的 observer
在 observer 中传入 baseComponent 组件,传参执行后使用 useObserver 包了一层并将其返回
所以连接函数组件的核心就是:useObserver

- useObserver
先通过 hooks 写了个 useForceUpdate,和类组件的 this.forceUpdate 同理,即重新执行函数组件
然后 new Reaction,onInvalidate 传的是 forceUpdate,下面 track 放在 useObserver 中执行,里面调用 fn(即 view),即每次 render,reaction 都能收集组件中依赖的 observable 并返回其值供视图渲染
同时利用闭包将 fn 执行的结果 rendering return 出去供 react 使用
另一方面组件依赖的 observable 变化后会触发 onInvalidate,注意这里是 forceUpdate,会重新走一遍函数组件,从而绑定新一轮的依赖
所以为什么不能在 Reaction 构造函数中直接传 view,因为 fn 执行的结果 react 会使用,而且通过 state 改变导致的 render 与 mobx 无瓜,你不能全靠 mobx 帮你执行 view 呀
mobx 要做的就是通知重新渲染,即调用 forceUpdate,这也是我们对 mobx-react 的最初理解嘛
再补充下 autorun,为啥要将 track 和 view 凑在一起形成 onInvalidate(数据变化时 onInvalidate 调用 track,track 调用 view 收集依赖并更新视图),其实说白了就是 autorun 没有像 forceUpdate 一样,重新执行 autorun 的能力,你细品

- useForceUpdate
熟悉 hooks 应该一下就猜到了,其实就是个 useState
创建一个 useState,将 setTick 方法返回,每次执行 setTick 不就 forceUpdate 了吗
useUnmount 更简单,不说了

- 像组件一样是使用:Observer
也很简单,获取 children 用 useObserver 包一下完事

二、连接 class 组件
然后看看 mobx-react 项目中处理 class 组件,换汤不换药,两点:
-
Reaction 构造函数中传 forceUpdate
-
调用 track 时执行 view,利用闭包将结果返回给 react
- observer class
首先判断是否为 forwardRef 函数,用上面说的 Observer 组件连接
普通函数组件用 mobx-react-lite 导出的 observer 即可

- makeClassComponentObserver
先对 props 和 state 简单劫持,获取 get 和 set 代理从而提交 reportObserved 和 reportChanged(详见:第三篇)
然后获取 baseRender 传入 makeComponentReactive
componentWillUnmount 也重写了下,为了调用 reaction.dispose

- makeComponentReactive
不用多说,看图

最后
-
欢迎在 mobx 源码解读 issue 中讨论~
-
推荐:
minbx: mini mobx
,供学习使用,欢迎 pr:minbx 项目地址 -
码字不易,喜欢的记得点 ❤️ 哦
ps:整个系列都完结了那些常年白嫖的,该出来点点赞,留留言的吧
pps:祝各位都能所有收获,有问题 issue 见~~