You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在类内部触发Mobx的reaction以响应observable变化?

解决Mobx类内部reaction无法触发的问题

你的代码存在两个核心问题导致reaction不触发,以下是修正方案和原因说明:

问题分析

  1. reaction创建时机错误:原代码中先创建reaction,再调用makeAutoObservable,此时类的属性还未被Mobx标记为可观察对象,reaction无法追踪后续变化。
  2. 错误引用外部变量:构造函数执行时,外部的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:15:40