网站搜索

typescript - 处理 mobx @computed 的响应


在以下文章中,它说 mobx 的反应应该被释放:https://mobxjs.github.io/mobx/best/pitfalls.html

用 @computed 装饰的属性是一种反应,因此它们似乎也需要被销毁。问题是,与显式调用 autorun()、observe() 或其他反应不同,它们会返回一个销毁函数,@computed 装饰器似乎并没有让我们能够销毁该反应。

所以问题是——由 @computed 装饰器定义的反应应该如何处理?

不处理的问题可能会在以下例子中显现

export class Observed {
    @observable
    public x: number;
}

export class Observer {

   constructor(private member: Observed){
   }

   @computed
   get doubled(){
      return this.member.x*2;
   }
}

let member = new Observed();
let observer = new Observer(member);

// now pass observer as a model to some react component and use its doubled property

只要 'member' 处于活动状态,observer 就会保持活跃,除非包装 doubled() 的反应被处理掉。即使我们给 Observer 添加了一个 dispose() 函数并自己调用它,我也不明白我们如何能够访问 doubled() 的底层反应来处理它。

答案#1

计算值会被 MobX 自动处理(甚至在需要时重新实例化)。MobX 能够做到这一点,是因为这些值不应有副作用。因此,每当 MobX 发现没有观察者对计算值感兴趣时,它们就会被自动挂起,并取消订阅计算值可能使用的任何可观察对象。此时,它可能会被垃圾回收(例如因为拥有它的对象超出了作用域),或者因为有新的观察者注册而重新激活。

换句话说,在你的例子中,观察者(Observer)不会被保持活着(也不会在观察被观察者 Observed),它可以安全地被垃圾回收(GC)。它只有在你在某个地方间接地在反应中使用它时才会被保持活着,比如

const disposer = reaction(() => observer.double, x => console.log(x))