MobX 是一个基于信号的、经过实战测试的状态管理库,通过透明地应用函数式响应式编程(FRP)使状态管理变得简单和可扩展。它通过观察者模式自动追踪状态变化,当可观察状态发生变化时,MobX 会自动更新所有依赖该状态的派生值和反应。
核心概念
1. Observable(可观察状态)
使用 observable 或 makeObservable 将普通 JavaScript 对象、数组、Map 等转换为可观察对象。可观察状态的变化会被 MobX 自动追踪。
javascriptimport { observable } from 'mobx'; class TodoStore { @observable todos = []; @observable filter = 'all'; }
2. Action(动作)
动作是修改状态的唯一方式,使用 action 装饰器或 runInAction 函数包装状态修改逻辑。这确保了状态变化是可追踪和可预测的。
javascriptimport { action } from 'mobx'; class TodoStore { @action addTodo(text) { this.todos.push({ text, completed: false }); } }
3. Computed(计算值)
计算值是基于可观察状态自动更新的派生值,类似于 Vue 的 computed 属性。只有当依赖的可观察状态发生变化时才会重新计算。
javascriptimport { computed } from 'mobx'; class TodoStore { @computed get activeTodos() { return this.todos.filter(todo => !todo.completed); } }
4. Reaction(反应)
反应是当可观察状态变化时自动执行的副作用,类似于 React 的 useEffect。常用的反应类型包括 autorun、reaction 和 when。
javascriptimport { autorun } from 'mobx'; autorun(() => { console.log('当前待办事项数量:', this.todos.length); });
工作原理
MobX 的工作流程:
- 追踪阶段:当反应或计算值读取可观察状态时,MobX 会建立依赖关系
- 变化阶段:通过 action 修改可观察状态
- 通知阶段:MobX 自动通知所有依赖该状态的反应和计算值
- 更新阶段:反应和计算值自动重新执行或重新计算
与 Redux 的区别
| 特性 | MobX | Redux |
|---|---|---|
| 状态管理 | 自动追踪,无需手动订阅 | 需要手动订阅和 dispatch |
| 代码量 | 较少,更简洁 | 较多,需要定义 actions、reducers |
| 学习曲线 | 较平缓 | 较陡峭 |
| 状态结构 | 可以嵌套 | 推荐扁平化 |
| 调试工具 | MobX DevTools | Redux DevTools |
最佳实践
- 始终使用 action 修改状态:确保状态变化可追踪
- 合理使用 computed:避免重复计算,提高性能
- 避免过度使用 observable:只对需要追踪的状态使用
- 使用 makeAutoObservable:简化装饰器配置
- 分离业务逻辑和 UI:将状态管理逻辑集中在 store 中
适用场景
MobX 适用于:
- 中大型 React 应用
- 需要复杂状态管理的项目
- 团队希望快速开发的项目
- 状态结构复杂且嵌套的场景
不适用于:
- 非常简单的应用
- 需要严格时间旅行调试的场景
- 团队偏好函数式编程范式