在 MobX 中,observable、computed 和 action 是三个核心概念,它们各自有不同的用途和特点:
Observable(可观察对象)
用途:
- 创建可以被追踪的状态
- 当状态发生变化时,通知所有依赖它的观察者
使用方式:
javascriptimport { observable } from 'mobx'; class Store { @observable count = 0; @observable user = { name: 'John', age: 30 }; @observable items = []; } // 或者使用函数式 API const store = observable({ count: 0, user: { name: 'John', age: 30 }, items: [] });
特点:
- 可以装饰类属性或创建可观察对象
- 支持对象、数组、Map、Set 等数据结构
- 深度可观察:嵌套的对象也会自动变为可观察的
- 在 MobX 6 中,默认使用装饰器 API 或
makeObservable
Computed(计算属性)
用途:
- 创建派生值,这些值基于其他 observable 状态自动计算
- 具有缓存机制,只在依赖项变化时重新计算
- 避免重复计算,提高性能
使用方式:
javascriptimport { observable, computed } from 'mobx'; class Store { @observable firstName = 'John'; @observable lastName = 'Doe'; @computed get fullName() { return `${this.firstName} ${this.lastName}`; } } // 或者使用函数式 API const store = observable({ firstName: 'John', lastName: 'Doe' }); const fullName = computed(() => `${store.firstName} ${store.lastName}`);
特点:
- 只读属性(默认情况下)
- 自动缓存计算结果
- 只有当依赖的 observable 变化时才重新计算
- 可以被其他 computed 或 observer 使用
- 懒计算:只有在被访问时才会计算
Action(动作)
用途:
- 封装状态修改逻辑
- 确保状态修改是可追踪和可预测的
- 在 MobX 6 中,所有状态修改都必须在 action 中进行
使用方式:
javascriptimport { observable, action } from 'mobx'; class Store { @observable count = 0; @action increment() { this.count++; } @action.bound decrement = () => { this.count--; }; @action async fetchData() { this.loading = true; const data = await api.getData(); this.data = data; this.loading = false; } } // 或者使用函数式 API const store = observable({ count: 0 }); store.increment = action(() => { store.count++; });
特点:
- 在 MobX 6 中是强制性的
- 可以是同步或异步的
action.bound会自动绑定this- 可以嵌套使用
- 提供更好的调试体验和可预测性
三者的关系
- Observable 是基础,提供可观察的状态
- Computed 依赖于 observable,自动计算派生值
- Action 用于修改 observable,触发依赖更新
最佳实践
-
使用 observable:
- 只对需要追踪的状态使用 observable
- 避免对整个应用状态都使用 observable
- 使用
makeAutoObservable自动推断
-
使用 computed:
- 用于计算派生值,而不是在组件中计算
- 避免在 computed 中产生副作用
- 复杂的计算逻辑使用 computed
-
使用 action:
- 所有状态修改都应该在 action 中进行
- 异步操作也应该包装在 action 中
- 使用
action.bound避免绑定问题
性能考虑
- Observable 本身不会带来性能开销
- Computed 通过缓存机制提高性能
- Action 帮助批量更新,减少不必要的重新渲染
理解这三个概念的区别和正确使用它们,是掌握 MobX 的关键。