10

我有这个小提琴

let m = new Mine();
this.setState(m, () => {
    console.log('1:', m instanceof Mine, m.x, m.meth);
    // => 1: true 123 function meth() {}
    console.log('2:', this.state instanceof Mine, this.state.x, this.state.meth);
    // => 2: false 123 undefined
});

如您所见,我创建了 Mine 类的一个实例,然后使用该实例在反应组件中设置状态。

我希望 this.state 包含该实例,但是虽然在构造函数中设置的实例属性可用,但我无法访问该实例上的任何类方法。

小提琴中的测试表明 this.state 不是 Mine 类的实例。

有人了解发生了什么还是这种意外行为?

4

3 回答 3

5

经过更多调查,我发现了发生这种情况的原因。

react 的 _processPendingState 函数使用 Object.assign 来设置新状态,因此由于目标对象是一个新对象(与传递给 setState 的对象不同),因此新状态失去了作为“Mine”类实例的质量。

而且由于 Object.assign 仅将自己的可枚举属性从源复制到目标,因此新状态也不会具有类方法。

如果在小提琴中我们替换线......

let m = new Mine();

和...

let m = {x: 123};
Object.defineProperty(m, 'meth', {
    enumerable: false,
    get() { return function() {}; }
});

我们仍然没有结果状态的“meth”属性。即使“m”拥有“meth”属性,它也是不可枚举的。

于 2016-07-20T12:24:59.930 回答
4

最好的解决方案是将方法表面化为箭头函数:

class Blah {
  constructor() {
    // no definition here for surfacedMethod!
  }

  surfacedMethod = () => {
    // do something here
  }

}

然后,您可以在 setState 中设置此类的实例并使用它们的方法,就好像它们是在实例上设置的属性一样。

// other component innards
this.setState(state => ({blah: new Blah()}))

// later
this.state.blah.surfacedMethod();  // this will now work
于 2018-01-09T01:48:12.323 回答
0

在这种情况下使用replaceState,它应该工作。

于 2016-07-20T09:55:54.997 回答