简体   繁体   English

如何避免 React.js 中的这种无限更新循环?

[英]How can I avoid this infinite update loop in React.js?

I have a parent component that has an index property in its state.我有一个父组件,它的 state 中有一个index属性。 When the index changes, I want it to pass new data to a child component in its props.当索引更改时,我希望它将新数据传递给其道具中的子组件。

When the child component receives new data, I want it to make an AJAX call to update its own state.当子组件收到新数据时,我希望它调用 AJAX 来更新自己的 state。 I cannot use componentDidUpdate() because this method runs when props or state changes.我不能使用componentDidUpdate()因为这个方法在 props 或 state 改变时运行。 So, I basically get this happening:所以,我基本上得到了这种情况:

  1. Parent passes new props家长传递新道具
  2. Child runs componentDidUpdate()子运行componentDidUpdate()
  3. Child runs fetchFromServer() , which updates state Child 运行fetchFromServer() ,它会更新 state
  4. Child runs componentDidUpdate()子运行componentDidUpdate()
  5. To infinity...到无穷远...

Is there a method for example that only runs when a component's props are updated?例如,是否有一种方法仅在组件的道具更新时运行?

Parent Component父组件

export default class ResultsFrame extends Component {

  constructor(props) {
    super(props);

    this.state = {
      
      resultIndex: 0,

    }
  }

  render() {

    return (

        <SequenceView data={this.props.results.results[this.state.resultIndex]}/>

    );
  }
}

Child Component子组件

export default class SequenceView extends Component {

  constructor(props) {
    super(props);

    this.state = {
      data: {},
      isLoading: true,
    }

  }

  render() {

    if(this.state.isLoading)
    {
      return ( <Spinner /> );
    }
    else
    {
      return (
        <div>

          {/* Render relevant stuff... */}

        </div>
      );
    }

  }

  componentDidMount()
  {
    this.fetchFromServer();
  }

  componentDidUpdate()
  {
    this.fetchFromServer();
  }

  fetchFromServer = () =>
  {
    const sendData = {
      data: this.props.data,
    };

    axios.post(`/analysis/seqview`, sendData)
      .then(res => {
        const response = res.data;
        console.log(response);
        this.setState({data: response, isLoading: false});
      })
      .catch(function (e) {
        console.log(e.response.data.message);
      });
  }
}

From the documentation从文档

You may call setState() immediately in componentDidUpdate() but note that it must be wrapped in a condition like in the example above, or you'll cause an infinite loop.您可以立即在 componentDidUpdate() 中调用 setState(),但请注意它必须包含在上面示例中的条件中,否则将导致无限循环。

This is exactly what you are doing here.这正是您在这里所做的。 your componentDidUpdate calls fetchFromServer which sets the state.您的 componentDidUpdate 调用fetchFromServer设置 state。

You need to change your componentDidUpdate to您需要将您的 componentDidUpdate 更改为

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

Refer:参考:

https://reactjs.org/docs/react-component.html#componentdidupdate https://reactjs.org/docs/react-component.html#componentdidupdate

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM