【问题标题】:ComponentDidUpdate SetState ReactJS Infinite loopComponentDidUpdate SetState ReactJS 无限循环
【发布时间】:2016-10-22 13:53:03
【问题描述】:

即使有很多问题都具有相同的主题行,我也无法得到我的问题的答案。

问题

我有一个选择下拉菜单。点击其中,我调用了一个获取一些键值的 Api。我将这组键值输入字段视为一个组件。因此,每次选择下拉菜单的 onChange 时,我都使用生命周期方法来处理 API 调用。此外,我记录这些输入键值并将它们的状态发送回父组件。

根据 ReactJS 生命周期方法:

我用

componentDidMount 在初始渲染后首次调用 API。这行得通。

componentDidUpdate 在选择下拉更改时调用 API 以进行后续 API 调用。但问题就在这里。当我尝试更新输入字段的状态时,程序陷入无限循环,因此存在无限 API 调用。调试后我很确定问题出在 setState() 上,但是我找不到在 componentDidUpdate 方法中处理状态的最佳方法。

这个link 完全复制了我的问题,但我想要一个标准化的解决方案

希望这很清楚。 提前感谢您的帮助!

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    是的,您不能在 componentDidUpdate 中设置状态(),这将导致无限循环。相反,您可以调用函数 onChange 事件并在那里更改状态。

    【讨论】:

    • 谢谢!我了解解决方法。但是 ReactJS 文档建议我们可以在 componentDidUpdate 中设置状态。想知道我是如何误解这个概念的。 busypeoples.github.io/post/react-component-lifecycle请查看此博客,您能告诉我哪里出错了吗?
    • 当您在 componentDidUpdate 中 setState() 时,它会调用以下生命周期: shouldComponetUpdate-->componentWillUpdate--->render---再一次 ---->componentDidUpdate 。这样就创建了无限循环。
    • 这是错误的。你可以componentDidUpdate中拨打setState,请看我的回答。
    【解决方案2】:

    这是因为 setState 触发了对 componentDidUpdate 的调用。

    当 componentDidUpdate 被调用时,setState 不会检查是否发生了状态改变。它只是一次又一次地调用componentDidUpdate,这会导致stackoverflow。

      class Component extends React.Component{
        constructor(props){
          super(props);
          this.state = {changeState: false}
        }
        componentDidMount(){
          this.setState({changeState: true});
        }
        componentDidUpdate(){
            this.setState({changeState: false});
        } 
     }
    

    这里首先在构造函数中将changeState设置为false,然后触发componentDidMount,将changeState的状态设置为true。此状态更改触发 componentDidUpdate,它将 changeState 的状态再次设置为 true。这会一次又一次地触发 componentDidUpdate。

    【讨论】:

      【解决方案3】:

      the docs 中清楚地说明了这一点:

      componentDidUpdate(prevProps) {
        // Typical usage (don't forget to compare props):
        if (this.props.userID !== prevProps.userID) {
          this.fetchData(this.props.userID);
        }
      }
      

      可以立即在 componentDidUpdate() 中调用 setState() 但请注意 它必须被包裹在一个条件中,就像上面的例子一样,或者 你会导致一个无限循环。

      【讨论】:

      • 你好@Madbreaks我有一个计时器,我只是在状态下定义一个计数器,当componentDidMount我做setInterval来减少计时器和组件更新我想在我的屏幕上将颜色更改为文本但我得到同样的错误componentDidUpdate() { if (this.state.timer === 0) { clearInterval(this.interval); this.setState({ resendColor: '#257bd1', // disable: false, }); } }
      【解决方案4】:

      您可以在componentDidUpdate() 中使用setState()。但是你必须为此使用条件。否则会无限循环。

      例如,

       componentDidUpdate(){
          if(this.props.id !== this.state.id) {
              this.setState({
                  id: this.props.id 
              });
          }
       }
      

      【讨论】:

        【解决方案5】:

        您必须检查两个状态对象之间的真正区别。 您可以在下面找到我的解决方案,我的状态对象有电影,它是一个对象数组。我编辑和电影,然后比较这两个数组。

            async componentDidUpdate(prevProps, prevState) {
        
                if (prevState.movies.filter (e => this.state.movies.includes(e))) {
                const response = await axios.get("http://localhost:3002/movies");
                this.setState({ movies: response.data })
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-08-26
          • 2021-07-12
          • 1970-01-01
          • 1970-01-01
          • 2021-05-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多