Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ComponentDidUpdate设置状态反应JS无限循环_Javascript_Reactjs - Fatal编程技术网

Javascript ComponentDidUpdate设置状态反应JS无限循环

Javascript ComponentDidUpdate设置状态反应JS无限循环,javascript,reactjs,Javascript,Reactjs,尽管有很多问题都是同一个主题,但我的问题还是找不到答案 问题 我有一个选择下拉列表。单击它,我调用一个Api,它获取一些键值。我把这组键值输入字段看作是一个组件。所以每次更改select下拉列表时,我都使用生命周期方法来处理API调用。此外,我记录这些输入键值并将其状态发送回父组件。 根据ReactJS生命周期方法: 我用 组件安装 在初始渲染后首次调用API。这很有效 组件更新 要为后续API调用调用调用API,请选择下拉更改。但问题是。当我尝试更新输入字段的状态时,程序陷入无限循环,因此

尽管有很多问题都是同一个主题,但我的问题还是找不到答案

问题

我有一个选择下拉列表。单击它,我调用一个Api,它获取一些键值。我把这组键值输入字段看作是一个组件。所以每次更改select下拉列表时,我都使用生命周期方法来处理API调用。此外,我记录这些输入键值并将其状态发送回父组件。

根据ReactJS生命周期方法:

我用

组件安装 在初始渲染后首次调用API。这很有效

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

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

希望这是清楚的。
提前谢谢你的帮助

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

发生这种情况是因为setState触发了对componentDidUpdate的调用

调用componentDidUpdate时,setState不会检查是否发生状态更改。它只是一次又一次地调用componentDidUpdate,这会导致堆栈溢出

  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一次又一次。

这一点在以下章节中有非常清楚的说明:

您可以在componentDidUpdate()中立即调用setState(),但请注意 它必须包装在一个条件中,如上例所示,或者 你将导致一个无限循环

您可以在
componentdiddupdate()
中使用
setState()
。但是你必须使用这个条件。否则,它将得到无限循环

例如,

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

您必须检查两个状态对象之间的实际差异。 下面你可以找到我的解决方案,我的状态对象有电影,这是一个对象数组。我编辑并制作了一部电影,然后比较了这两个数组

    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 })
    }
}

谢谢我了解解决办法。但是ReactJS文档建议我们可以在componentDidUpdate中设置状态。我想知道我是怎么误解这个概念的。请查看此博客,您能告诉我哪里出了问题吗?当您在componentDidUpdate中设置state()时,它将调用以下生命周期:shouldComponentUpdate-->componentWillUpdate-->render--然后再次-->componentDidUpdate。这样它就创建了无限循环。这是错误的。您可以在
componentdiddupdate
中调用
setState
,请查看我的答案。Hello@Madbreaks我有一个计时器,我只是在状态中定义了一个计数器,当componentDidMount时,我执行setInterval以减少计时器,在component确实更新中,我想在屏幕中将颜色更改为文本,但我收到了相同的错误
componentdiddupdate(){if(this.state.timer==0){clearInterval(this.interval);this.setState({resendColor:'#257bd1',//disable:false,});}}
    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 })
    }
}