Javascript 为什么会出现此错误:“quot;不变冲突:无法在现有状态转换期间更新“;

Javascript 为什么会出现此错误:“quot;不变冲突:无法在现有状态转换期间更新“;,javascript,reactjs,react-native,Javascript,Reactjs,React Native,我似乎在一个大型应用程序中遇到了这个错误(但我不确定具体发生在哪里): 未捕获错误:不变冲突:设置状态(…):无法更新 在现有状态转换期间(例如在渲染中)。伦德尔 方法应该是道具和状态的纯函数 我怀疑这可能是由于在setTimeout或setInterval中使用setState造成的 这就引出了我真正的问题:为什么会存在这种错误?我不知道为什么ReactJS不只是队列状态和道具更改,有什么概念上的原因吗?我猜是否有原因,它与应用程序的复杂性和/或避免竞争条件有关 接下来我的问题是:在React

我似乎在一个大型应用程序中遇到了这个错误(但我不确定具体发生在哪里):

未捕获错误:不变冲突:设置状态(…):无法更新 在现有状态转换期间(例如在
渲染中)。伦德尔
方法应该是道具和状态的纯函数

我怀疑这可能是由于在
setTimeout
setInterval
中使用
setState
造成的

这就引出了我真正的问题:为什么会存在这种错误?我不知道为什么ReactJS不只是队列状态和道具更改,有什么概念上的原因吗?我猜是否有原因,它与应用程序的复杂性和/或避免竞争条件有关

接下来我的问题是:在React之外(例如在某个异步事件期间)更新组件以避免发生此错误的正确方法是什么

编辑:


在深入研究这个问题之后,似乎罪魁祸首实际上是我正在使用的底层平台(ElectronJS,正式称为Atom Shell)。基本上,ElectronJS将铬和NodeJS结合在一起。我用一个NodeJS API做了一些异步的事情,当它完成时,ElectronJS会返回到它停止的调用堆栈,完全绕过事件循环,从而导致React的竞争条件。

实现这一点的一种方法是使用流量模式,并让超时触发存储中的更改。这将导致更改作为其生命周期的一部分传播到感兴趣的组件。

问题是
setState
将导致重新呈现(可能取决于
shouldComponentUpdate
)。如果在
render
函数中有一个
setState
调用,它将触发另一个渲染。你很可能会陷入无限的重新渲染循环中。由于某些异步操作,没有任何东西可以阻止您使用
setState
(事实上这很常见)。只要它不在状态更新中运行的组件的
渲染
或其他生命周期方法中(
shouldComponentUpdate
是另一种方法,因为您将以相同的方式结束无限循环)。

React将在必要时批处理
设置状态
调用,我在React+Electron上也遇到了同样的问题,错误不断出现。似乎它不会破坏应用程序,但仍然很烦人。你找到解决方法了吗?我的解决方案与
setImmediate(//可能调用setState的函数)
@fraserxv类似。它源自library request.js,它使用下面的节点http库。基本上,我必须在响应回调中放入
setTimeout
(与
setImmediate
相同)的
setTimeout
),然后问题就消失了。仅供参考,我不久前在Electron的Github上报告了这个问题,但它仍然是一个wontfix。“在Electron中,Node.js的任务队列和browser的任务队列是独立的,因此无法保证setTimeout和Node.js API的任务会按顺序运行。而且web标准也从未保证setTimeout回调的顺序,因此我认为当前的行为是可以的。”这里有一个具体的问题:如果它必须在渲染中怎么办?我的意思是,我仍然会得到一个无法避免的错误,但唯一的解决办法是使用if语句来停止无限for循环