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

如何在Coffeescript中使用MobX 4实现计算值?

解决MobX 4中extendObservable传入computed实例报错的问题

这个问题我之前也碰到过!MobX 4对extendObservable的行为做了关键调整,导致你在MobX 3里的写法不再兼容。

原MobX 3代码(报错版本)

mobx = require 'mobx'
state = mobx.observable items:['a','b']
compute = (key,fn)->
    obj = {}
    obj[key] = mobx.computed fn.bind state
    mobx.extendObservable state, obj
compute 'num', -> @items.length
mobx.autorun -> console.log "items = #{state.items}"
mobx.autorun -> console.log "num = #{state.num}"
state.items.push 'c'

报错原因

MobX 3允许直接将mobx.computed()创建的实例作为值传入extendObservable,但MobX 4重构了响应式属性的初始化逻辑,禁止这种做法——它现在要求通过属性描述符对象(包含get方法的对象)来定义计算属性,这样MobX才能正确处理依赖追踪和属性的响应式绑定。

修复后的MobX 4兼容代码

我们可以修改compute函数,通过属性描述符的方式定义计算属性:

mobx = require 'mobx'
state = mobx.observable items:['a','b']
compute = (key, fn)->
    # 使用带有get方法的描述符对象
    mobx.extendObservable state,
        "#{key}":
            get: fn.bind state
compute 'num', -> @items.length
mobx.autorun -> console.log "items = #{state.items}"
mobx.autorun -> console.log "num = #{state.num}"
state.items.push 'c'

或者,也可以直接使用mobx.defineProperty来更直观地定义计算属性:

mobx = require 'mobx'
state = mobx.observable items:['a','b']
compute = (key, fn)->
    mobx.defineProperty state, key,
        get: fn.bind state
compute 'num', -> @items.length
mobx.autorun -> console.log "items = #{state.items}"
mobx.autorun -> console.log "num = #{state.num}"
state.items.push 'c'

验证效果

修复后的代码运行后,当执行state.items.push 'c'时,两个autorun都会正确触发,输出:

items = a,b,c
num = 3

完全符合预期。

内容的提问来源于stack exchange,提问作者Nick Perkins

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:15:29