2024-06-09
ReactJS
00
请注意,本文编写于 90 天前,最后修改于 89 天前,其中某些信息可能已经过时。

目录

mobx@4 用法
mobx@4 的问题
mobx@4 升级到5
mobx@4性能优化

最近工作中遇到了mobx的坑,与Vue2数据劫持一样的坑,没错东家项目中的mobx版本比较旧mobx@4.8,今天总结一下Mobx老版本及遇到的问题,再探索下mobx中的性能优化。

mobx@4 用法

mobx@4 与用法与我前面一篇文章对mobx的总结用法基本一致,只是有一些细微的区别

  1. 异步变更 不需要用runInAction包裹,没有警告。
  2. store 构造函数不需要用makeObservable包裹

mobx@4 的问题

官方有这么一段话

image.png

mobx<5 的实现 与 Vue2 一样,都是基于Object.defineProperty+覆盖数组的7个方法。所有Vue2响应式存在的问题 ,在mobx中同样存在。

  1. 对象劫持的问题--新加或删除属性无法监听
  • 无法监听删除属性

image.png

  • 无法监听新增的属性

image.png

当然也有解决方式 就是对变量 直接赋值新对象,代价是会有重复的渲染(一些组件引用了obj的属性,但值没有变化,也会渲染)。

  1. 数组的问题
js
import { action, observable} from 'mobx'; class AppState { @observable list = []; @action push = () => { this.list.push({id: Math.random()}); } } export default window.bb = new AppState()

如果我们对list进行操作,修改length,对数组元素进行赋值list[x]=xxx都没呕问题。但是不能修改数组元素属性list[x].name='xx'(失去了响应式)

然而这些问题在mobx>=5的版本中都没有问题

proxy 数据劫持,除了解决了上述问题,还有更好的性能提升

  • Object.defineProperty本质是对对象进行遍历,收集依赖进行递归便利不仅耗时,也产生了大量闭包造成内存占用,
  • Proxy是惰性执行,按需对数据劫持,有更好的性能

然而Proxy也并非完美,代理对象与原对象是不同的对象,对代理对象进行解构,会得到原始对象,对原始对象的操作没有响应性。

mobx@4 升级到5

对于react项目 mobx从4升到5,react也要配套升级

image.png

此外由于Proxy独特特性 babel不提供补丁,也就好说android>=7ios>=10的手机才能运行

mobx@4性能优化

前面提到 通过Object.assigndeepMerge的方式可以减少不必要的渲染,但是要注意前面的坑,也就是说必须事先声明好对象的完整keys。

本文作者:郭郭同学

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!