【发布时间】:2016-02-20 19:15:08
【问题描述】:
tl;dr:与 mridgway 在这里描述的相同问题:isMounted is not enough to know if you can setState
我有一个这样的组件层次结构:
PhasesList
- Phase
- PhaseHeader
- Phase
- PhaseHeader
还有一个 PhaseStore,它维护一个阶段列表及其详细信息。
在所有三个组件中,我侦听 PhaseStore 更改并根据更改更新状态(重新渲染)。例如,如果用户更改 PhaseHeader 中的阶段名称,我会触发操作、存储更新并发出更改事件。该更改事件被传播到以实际名称值呈现的 PhaseList、Phase 和 PhaseHeader。
有一个有问题的情况,我可以删除一个阶段。此操作在 PhaseStore 中处理,其中从列表中删除阶段并发出更改事件(与其他情况一样)。这个事件由所有组件处理,从上到下(因为都监听存储变化)。
因此,在 PhasesList 中,渲染了一组新的阶段,而没有删除一个。但是,被移除的阶段组件仍然会收到更改事件,PhaseHeader 也会收到。
在这两个组件中,在相变处理程序中我使用 setState。我收到的信息是这样的:
警告:setState(...):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了 setState()。这是无操作的。
我发现人们使用 isMounted 来检查组件是否仍在 DOM 中。此方法现已弃用。
我怎样才能以适当的、不断变化的方式解决这个问题?我的组件设计及其相互通信有什么问题?
【问题讨论】:
-
您可能需要确保在 componentWillUnmount 中禁用相变处理程序 - 我不确定这在您的特定情况下是否有效或足够。
-
没错,在
componentWillUnmount中,您应该清除/取消订阅您在componentDidMount中所做的所有事情 -
是的,我正在删除所有组件中的处理程序,这些组件在
componentWillUnmount中注册了该事件。这没有帮助。当存储更改事件被触发时,所有三个处理程序都会循环通过。在第一个处理程序(PhaseList)中,设置了新阶段。然后调用另外两个处理程序(Phase 和 PhaseHeader),其中已删除的阶段已经消失。 -
同样的问题stackoverflow.com/questions/32121231/… 通过将回调方法包装在一个函数中解决。出于某种原因,这确保了您的回调已从 Eventmitter 中删除。
-
刚刚看到关于 isMounted 弃用的公告。我同意非常好的解释和推理。不过,我仍然没有涵盖边缘情况 - 在 Flux 本身中引用回调(作为正在删除的父组件的子组件中注册的更改处理程序......)facebook.github.io/react/blog/2015/12/16/…
标签: reactjs flux reactjs-flux