当 setState 与类的对象实例发生反应时会发生啥

Posted

技术标签:

【中文标题】当 setState 与类的对象实例发生反应时会发生啥【英文标题】:what happens in react when setState with object instance of a class当 setState 与类的对象实例发生反应时会发生什么 【发布时间】:2016-11-23 10:55:56 【问题描述】:

我有这个fiddle

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 包含该实例,但在构造函数中设置的实例属性可用时,我无法访问该实例上的任何类方法。

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

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

【问题讨论】:

你的小提琴是空的,分享前需要保存。 可能是因为原型中的 meth()。尝试在构造函数 this.meth = this.meth jsfiddle.net/pb2uqr2o/1 中明确定义 另一个原型jsfiddle.net/pb2uqr2o/2的例子,它也不起作用 this.setState(...m, meth:m.meth);将工作。但我认为你不应该在状态中保留函数。 或 this.setState(m) 和 this.state.m.meth 【参考方案1】:

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

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”属性,它也是不可枚举的。

【讨论】:

这个 Github 问题似乎(简要地)谈论了同样的问题:github.com/facebook/react/issues/5425【参考方案2】:

最好的解决方案是将方法呈现为箭头函数:

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

【讨论】:

【参考方案3】:

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

【讨论】:

此方法在扩展 React.Component 的 ES6 类组件上不可用。它可能会在未来版本的 React 中完全删除。 使用 replaceState 它确实可以工作,但正如 Ultro 所说,它将来可能会被删除,所以我不愿意使用它。 @KokovinVladislav 我正是需要这种方法。 2017 年的替代方案是什么?我似乎找不到任何好的方法来保留一个类的实例......每个好的函数 react 都被一个一个删除

以上是关于当 setState 与类的对象实例发生反应时会发生啥的主要内容,如果未能解决你的问题,请参考以下文章

调用setState时会发生什么?

Java基础对象与类

Java类的定义与类的实例化

如何使用我的反应应用程序中的 useState 钩子给出的 setState 方法增加状态对象的选定索引的计数

如果有的话,在 java 中声明给定类的空对象字段时会发生哪些特定于类的操作?

反应对象的本机 setState/useState