如何在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
相关产品推荐
相关产品推荐

