如何修改MobX observable对象内方法this上下文以访问外部函数
问题根因
action.bound 是MobX提供的强制绑定上下文的API,被它包裹的函数执行时,this会被永久固定到对应的observable实例上,不会向外层作用域查找上下文。所以在被绑定的loadAll方法中写this.request(),只会查找observable对象自身挂载的属性,找不到外层独立定义的request函数时就会抛出引用错误。
可行解决方法
- 直接调用外层作用域的
request,不通过this访问
独立定义在observable外层的request本身就在当前闭包可访问范围内,不需要借助this引用,直接调用即可,是改动成本最低的方案。// 外层独立定义的函数 request = () => { console.log('hello'); } base = observable({ isDeleting: false, registry: observable.map(), get all() { return this.registry.values(); }, loadAll: action.bound(function () { console.log(this); // 输出当前base observable实例,可正常访问所有响应式属性 request(); // 直接调用外层函数,无需走this }), }); - 放弃
action.bound,用箭头函数定义action继承外层上下文
箭头函数不会生成独立的this,会直接继承定义位置的外层上下文,这种写法下loadAll内的this就是你需要的类整体上下文,可以直接访问外层挂载的request方法。注意:这种写法下你无法在loadAll内通过this访问base自身的响应式属性,如果需要同时操作base的响应式状态,不建议选这个方案。base = observable({ isDeleting: false, registry: observable.map(), get all() { return this.registry.values(); }, // 不使用bound绑定,箭头函数继承外层this loadAll: action(() => { console.log(this); // 输出外层类/组件的整体上下文 this.request() // 直接访问外层挂载的request方法 }), }); - 将
request挂载到observable对象上,用箭头函数保留外层上下文
也就是你示例中写出的实现方式,把request作为base的属性定义,用箭头函数写法时,request内部的this会指向外层上下文,同时loadAll绑定的this依然可以正常访问base自身的所有响应式属性。适合request逻辑和base强绑定、不需要跨场景复用的场景。base = observable({ isDeleting: false, registry: observable.map(), get all() { return this.registry.values(); }, loadAll: action.bound(function () { console.log(this); // 指向base实例,可正常操作响应式属性 this.request() }), request: () => { console.log(this) // 指向对象外部的目标上下文 console.log('hello'); }, });
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

