开发者问题收集

如何处理对 mobx 中已修饰的超类方法的调用

2017-10-02
1064

即使我知道不鼓励继承并且组合应该更好,我还是想知道如何使用 mobx 状态类处理继承并调用已经用 @action.bound 装饰的超类方法。

我有这个代码示例(可以在舒适的 jsfiddle 中轻松执行):

const { observable, action } = mobx;

class Store {
    @observable list = []
  @observable num = 0

  constructor() {
    console.log('Store ctor')
  }

  @action.bound
  reset() {
    this.list.clear()
    this.num = 0
  }
}

class StorePlus extends Store {
    @observable num2 = 0

  constructor() {
    super()
   }

   @action.bound
   reset() {
    super.reset()
    this.num2 = 0
   }
}

const storePlus = new StorePlus()
storePlus.reset()

由于这个错误而被破坏:

Uncaught RangeError: Maximum call stack size exceeded

我理解问题出在调用 super.reset 上,其中 reset 是一个已经修饰的超类方法。但是我不了解内部原理,也不知道使用组合而不是继承的最佳方法是什么,避免编写一些适配器方法来公开父类可观察对象和操作方法。

希望我的问题清楚!

2个回答

我不确定具体原因,但问题在于 action.bound

如果在构造函数中绑定 this 并将结果包装在操作中(像这样... this.reset = action(this.reset.bind(this) ),那么它似乎工作正常。

https://jsfiddle.net/cr82ktdd/

const { observable, action } = mobx;
console.clear()

class Store {
  @observable list = []
  @observable num = 0

  constructor() {
    console.log('Store ctor')

    this.reset = action(this.reset.bind(this))
  }

  reset() {
    console.log('Store reset')
    this.list.clear()
    this.num = 0
  }
}

class StorePlus extends Store {
    @observable num2 = 0

  constructor() {
    super()

    this.reset = action(this.reset.bind(this))
   }

   reset() {
    console.log('StorePlus reset')
    super.reset()
    this.num2 = 0
   }
}

const storePlus = new StorePlus()
storePlus.reset()
Steve Ladavich
2018-05-24

问题是您无法重新分配已经绑定的操作 JavaScript 不支持将多个上下文绑定到同一函数。 删除 bound 并单独进行绑定

const storePlus = new StorePlus() storePlus.reset = storePlus.reset.bind(storePlus) storePlus.reset()

Andranik
2018-11-07