效率至上的Mobx
为什么会考虑使用状态管理?
项目开发中经常会碰到以下场景: 1.业务系统许多接口,入参都需要传递登陆人 id
1 |
|
2.业务系统选择下拉框,如城市,销售业务员、车型、折旧选项等均为同一接口数据。
1 |
|
3.兄弟组件传值等
MobX 背后的哲学
任何可以从应用程序的状态中获取/衍生的数据都应该可以自动被获取/衍生。
MobX 遵循单项数据流,通过 action 改变 state(可观测对象),state 的变化又会触发 computed value 和 reaction 的重新执行。
Redux 和 Mobx 相同点
1.优秀的状态管理解决方案 2.采用单向数据流管理状态 3.Action-->State-->Views
Mobx 和 Redux 的区别
Mobx | Redux |
---|---|
多个 store 对象,多 store 间的数据共享、相互引用 | 单一数据源,应用共享一个 store 对象 |
state 结构可以任意嵌套 | state 结构尽可能的扁平化,从而减少嵌套层级 |
state 可观测,可以直接修改 | 普通 JavaScript 对象存储 state |
上手成本低、开发效率高 | 需要熟悉函数式编程基础 |
代码量更少 | 需要写更多的代码来执行严格的规范 |
选择
MobX | Redux |
---|---|
相对简单的应用 | 复杂度较高的应用 |
MobX 包含的主要概念
- state(状态)
- computed value(计算值)
- reaction(响应)
- computed value 和 reaction 会自动根据 state 的改变做最小化的更新
- action(动作)
Mobx 的缺点
如使用装饰器时团队如果不制定一个规范,后期可能难以维护。
解决方案
自定义装饰器还是要在项目组内达成共识才行。
如:将各个状态封装到一个对象中导出(防止代码难以维护,加入静态图和 gif 图)
将使用 Mobx 观测的数据整合到一个 stores 对象注入到 Provider
到‘src/stores/index.js’中
获取可观测的 state
通过 React-mobx 提供 Provider 组件在根目录 index.jsx 中让容器组件拿到 state
1 |
|
Provider 在根组件外包了一层,来让 App 的所有子组件就默认都可以拿到 state。
Provider 源码
只有先获取到 state,在对应组件中才能使用 inject 注入
@inject 注入使用的 Store
1 |
|
配置装饰器语法
项目中会大量使用到装饰器语法@observable,所以要提前配置装饰器
配置方案
记得配置 jsconfig
computed value 的使用
一般通过computed
和@computed
创建computed value
1 |
|
action 的使用
常见的用法
1 |
|
action.bound 解决 this 指向问题
箭头函数
1 |
|
action.bound/@action.bound
1 |
|
1 |
|
mobx 调试工具
mobx-react-devtools 是一个用于调试 MobX+React 项目的工具,可以追踪组件的渲染以及组件依赖的可观测数据。
安装
只需要在开发环境下使用调试工具,安装命令使用的参数是–save-dev
1 |
|
再次运行程序,界面右上角会多出三个小图标,是 mobx-react-devtools 的功能键。
使用
点击第一个图标,当组件发生渲染行为时,对应的组件会被高亮显示
- 高亮组件右上角显示的 3 个数字分别代表截至当前组件渲染的次数、组件 render 方法执行的时间、组件从 render 方法开始到渲染到浏览器界面使用的时间
点击第二个图标后,再用鼠标选择任意一个组件,可以查看该组件会对哪些数据的变化做出响应
点击第三个图标,控制台会输出发生的 action、响应的 reaction 等调试日志信息
当然你也可以使用 trace 进行调试
参考
- Mobx 官方文档
- 我为什么从 Redux 迁移到了 Mobx
- 《React 进阶之路》–徐超