ComponentDidUpdate SetState ReactJS无限循环

时间:2016-06-21 06:44:00

标签: javascript reactjs

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

问题

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

根据ReactJS生命周期方法:

我用

componentDidMount      在初始渲染后第一次调用API。这很有效。

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

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

希望这很清楚。 我在这里先向您的帮助表示感谢!

5 个答案:

答案 0 :(得分:2)

是的,你不能在componentDidUpdate中使用setState()它会导致无限循环。相反,你可以调用函数onChange事件并改变那里的状态。

答案 1 :(得分:1)

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

g = df['Event'].eq('A').groupby(df['Id'])
df[(g.transform('sum') - g.cumsum()).le(1)]

   Id  Seqno. Event
2   1       5     A
3   1       6     A
4   1       7     D
6   2       1     A
7   2       2     B
8   2       4     A
9   2       6     B
  

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

答案 2 :(得分:1)

您可以在setState()中使用componentDidUpdate()。但是您必须为此使用条件。否则,它将陷入无限循环。

例如,

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

答案 3 :(得分:0)

这是因为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。

答案 4 :(得分:0)

您必须检查两个状态对象之间的实际差异。 在下面可以找到我的解决方案,“我的状态对象包含电影”,它是对象的数组。我编辑了电影,然后比较了这两个数组。

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