初始渲染/重新渲染后如何根据DOM节点信息设置状态? (反应)

时间:2019-08-06 09:42:55

标签: javascript reactjs state rerender

在我的框架中,在初始渲染和重新渲染之后,我需要有关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,但是后来我错过了关键的重新渲染,它将父状态传递给子级作为上下文。

2 个答案:

答案 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
          });
      }