为什么存在此错误:“不变违规:在现有状态转换期间无法更新” [英] Why does this error exist: "Invariant Violation: Cannot update during an existing state transition"

查看:330
本文介绍了为什么存在此错误:“不变违规:在现有状态转换期间无法更新”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎在大型应用程序中遇到此错误(但我不确定在哪里):

I seem to be running into this error in a large application (but I'm not exactly sure where):


未捕获错误:不变违规:setState(...):在现有状态转换期间无法更新
(例如在 render 中)。渲染
方法应该是道具和状态的纯函数。

Uncaught Error: Invariant Violation: setState(...): Cannot update during an existing state transition (such as within render). Render methods should be a pure function of props and state.

我怀疑它可能是使用<$的结果c $ c> setState 在 setTimeout setInterval 内。

I suspect it might be the result of using setState inside of setTimeout or setInterval.

这引出了我真实的问题:为什么会出现这个错误?是否有一些概念上的原因我不知道为什么ReactJS不只是排队状态和道具变化?我猜是否有原因,它与应用程序复杂性和/或避免竞争条件有关...

Which leads me to my real question: why does this error exist? Is there some conceptual reason I'm missing why ReactJS doesn't just queue state and prop changes? I'm guessing if there is a reason, it has to do with application complexity and/or avoiding race conditions...

我的下一个问题是:什么是在React之外更新组件的正确方法(例如在某些异步事件期间),以便不会发生此错误?

My next question then would be: what is the proper way to update a component outside of React (during some asynchronous event for example) so that this error doesn't occur?

编辑:

在进一步深入研究这个问题之后,看起来罪魁祸首实际上是我正在使用的基础平台(ElectronJS,正式的Atom Shell)。基本上,ElectronJS将Chromium和NodeJS结合在一起。我正在使用NodeJS API来做异步操作,当它完成后会出现,ElectronJS只会返回到它停止的调用堆栈,完全绕过事件循环,从而导致与React的竞争条件。

After some digging into this issue further, it appears the culprit is actually the underlying platform I'm using (ElectronJS, formally Atom Shell). Basically, ElectronJS combines Chromium and NodeJS together. I was using a NodeJS API to do something asynchronous and it appears when that finished, ElectronJS would just return back to the call stack where it left off, bypassing the event loop altogether and thus causing a race condition with React.

推荐答案

问题是 setState 会导致重新渲染(可能取决于 shouldComponentUpdate )。如果你在 render 函数中有一个 setState 调用,它将触发另一个渲染。你可能最终会进行无限循环的重新渲染。由于某些异步操作(实际上它很常见),没有什么可以阻止你使用 setState 。只要它不在 render 或在状态更新上运行的组件的某些其他生命周期方法( shouldComponentUpdate 成为另一个,因为你最终会以同样的方式进行无限循环。)

The issue is that setState will cause a re-render (potentially, depending on shouldComponentUpdate). If you had a setState call within the render function, it would trigger yet another render. You'd likely end up in an infinite loop of re-renderings. There's nothing that stops you from using setState as a result of some asynchronous operation (in fact it's very common). It's fine just as long as it's not in the render or some other lifecycle method of a component that is run on a state update (shouldComponentUpdate being another as you'd end up with an infinite loop in the same way).

这篇关于为什么存在此错误:“不变违规:在现有状态转换期间无法更新”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆