如何在类内部触发Mobx的reaction以响应observable变化?
解决Mobx类内部reaction无法触发的问题
你的代码存在两个核心问题导致reaction不触发,以下是修正方案和原因说明:
问题分析
- reaction创建时机错误:原代码中先创建reaction,再调用
makeAutoObservable,此时类的属性还未被Mobx标记为可观察对象,reaction无法追踪后续变化。 - 错误引用外部变量:构造函数执行时,外部的
giraffe变量还未完成实例赋值,reaction追踪的是一个未定义的对象属性,自然不会触发。
修正后的代码
import { makeAutoObservable, reaction } from "mobx" class Animal { name energyLevel #disposeReaction // 私有属性存储reaction清理函数 constructor(name) { this.name = name this.energyLevel = 100 // 第一步:先让Mobx标记类的可观察属性 makeAutoObservable(this) // 第二步:基于当前实例创建reaction this.#disposeReaction = reaction( () => this.isHungry, // 追踪当前实例的计算属性 (isHungry) => { if (isHungry) { console.log(`${this.name}:我饿啦!`) } else { console.log(`${this.name}:我不饿!`) } console.log(`${this.name}的能量值:`, this.energyLevel) // 在这里可以直接操作类内部其他数据或子存储 // 示例:this.subStore.updateState() } ) } reduceEnergy() { this.energyLevel -= 10 } get isHungry() { return this.energyLevel < 50 } // 销毁实例时清理reaction,避免内存泄漏 destroy() { this.#disposeReaction() } } // 测试示例 const giraffe = new Animal("长颈鹿") // 多次调用直到能量值低于50 for (let i = 0; i < 6; i++) { giraffe.reduceEnergy() } // 不需要实例时清理 giraffe.destroy()
关键要点
- 先标记可观察属性:必须确保
makeAutoObservable(或makeObservable)在reaction之前执行,让Mobx先完成对类属性的可观察性标记。 - 使用当前实例this:reaction内部通过
this访问类的属性/方法,确保追踪的是当前实例的可观察状态。 - 清理reaction:保存reaction返回的清理函数,在实例生命周期结束时调用,避免内存泄漏。
内容的提问来源于stack exchange,提问作者sir-haver
相关产品推荐
相关产品推荐

