在我的框架中,在初始渲染和重新渲染之后,我需要有关React组件在DOM中的状态的某些信息,然后我需要将其作为 context传递给子组件。
具体来说,我需要知道渲染的DOM节点是否是其父节点的第一个/最后一个子节点,并将此信息保留为状态,所以我正在做类似的事情:
componentDidUpdate() {
if (this.REF.current === this.REF.current.parentNode.firstChild) {
this.setState({ isFirstChild: true });
}
}
在此处调用 setState 会触发重新渲染,这是必需的,以便可以将值传递给子组件,这是通过 context 进行的-类似于(剥离下来):
render() {
const contextValues = {
...this.context,
...this.state
}
return (
<ContextProvider value={contextValues}>
{this.props.children}
</ContextProvider>
);
}
...现在在子组件中,我可以this.context.isFirstChild
来确定父级是否是其父级的第一个孩子。
问题...
设置状态导致重新渲染。重新渲染会导致设置状态。这会使React陷入无限循环,并产生以下错误:
Uncaught Invariant Violation: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate
在我看来,关于我的方法的某些事情是错误的。我只是不确定。我认为我不应该在这里使用setState
,但是后来我错过了关键的重新渲染,它将父状态传递给子级作为上下文。
答案 0 :(得分:1)
尝试一下:
componentDidUpdate() {
if (this.REF.current === this.REF.current.parentNode.firstChild) {
if (!this.state.isFirstChild) {
this.setState({ isFirstChild: true });
}
}
}
这样,您就不会重复调用setState并获得与您的状态已经包含的信息相同的信息。
答案 1 :(得分:0)
问题是每次组件更新时,您都在没有任何中断条件的情况下再次对其进行更新。这将创建一个无限循环。您应先检查this.state.isFirstChild
是否 true ,然后再在此处进行更新。
替换少量代码即可为您工作。
if (!this.state.isFirstChild) {
this.setState({
isFirstChild: true
});
}