乐闻世界logo
搜索文章和话题

MobX 中的 observable、computed 和 action 有什么区别?

2月19日 17:57

在 MobX 中,observable、computed 和 action 是三个核心概念,它们各自有不同的用途和特点:

Observable(可观察对象)

用途

  • 创建可以被追踪的状态
  • 当状态发生变化时,通知所有依赖它的观察者

使用方式

javascript
import { 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 状态自动计算
  • 具有缓存机制,只在依赖项变化时重新计算
  • 避免重复计算,提高性能

使用方式

javascript
import { 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 中进行

使用方式

javascript
import { 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
  • 可以嵌套使用
  • 提供更好的调试体验和可预测性

三者的关系

  1. Observable 是基础,提供可观察的状态
  2. Computed 依赖于 observable,自动计算派生值
  3. Action 用于修改 observable,触发依赖更新

最佳实践

  1. 使用 observable

    • 只对需要追踪的状态使用 observable
    • 避免对整个应用状态都使用 observable
    • 使用 makeAutoObservable 自动推断
  2. 使用 computed

    • 用于计算派生值,而不是在组件中计算
    • 避免在 computed 中产生副作用
    • 复杂的计算逻辑使用 computed
  3. 使用 action

    • 所有状态修改都应该在 action 中进行
    • 异步操作也应该包装在 action 中
    • 使用 action.bound 避免绑定问题

性能考虑

  • Observable 本身不会带来性能开销
  • Computed 通过缓存机制提高性能
  • Action 帮助批量更新,减少不必要的重新渲染

理解这三个概念的区别和正确使用它们,是掌握 MobX 的关键。

标签:Mobx