简体   繁体   中英

React app, componentDidUpdate - jumping list, infinite loop

I have react aplication. I would like to switch between id in url. Every click in the tab should show different kind of product list. I used from method componentDidUpdate. The problem is, when I click in the next tab, the list is jumping from previous list to the present list several times. I have read that it might be a problem with using setState in method componentDidUpdate and it can cause a infinite loop. I've tried something different things to do, but I have no idea, what I should change in my code. Could you have any idea, how to fix this jumping thing?

  constructor(props) {
    super(props);
    this.state = {
      food: []
    };
    var ingredient_type = this.props.params.id;

    fetch('/food/type/'+ingredient_type)
      .then(res => res.json())
      .then(food=> this.setState({food}));
  }


   componentDidUpdate(){
   var ingredient_type = this.props.params.id;

    return fetch('/food/type/'+ingredient_type)
      .then(res => res.json())
      .then(food=> this.setState({food}));
  }



    render() { 
      let product_list = this.state.food.map((product, id) => <div className="row" key={id}> 
                                  <p  className="cal_list col-lg-4 col-md-4 col-sm-4" >{product.name}</p> 
                                  <p  className="cal_list1 col-lg-2 col-md-2 col-sm-2" >{product.calories}</p> 
                                  <p  className="cal_list2 col-lg-2 col-md-2 col-sm-2" >{product.protein}</p> 
                                  <p  className="cal_list3 col-lg-2 col-md-2 col-sm-2" >{product.fat}</p>
                                  <p  className="cal_list4 col-lg-2 col-md-2 col-sm-2" >{product.carb}</p> </div>)

This is how I would handle your situation:

constructor(props) {
  super(props);
  this.state = {
    food: []
  };
}

componentDidMount() {
  fetchFood(this.props.params.id)
}

componentDidUpdate(prevProps) {
  if(this.props.params.id !== prevProps.params.id) {
    fetchFood(this.props.params.id)
  }
}

fetchFood(id) {
  return fetch('/food/type/'+id)
    .then(res => res.json())
    .then(food=> this.setState({food}));
}

render() {
  ...
}

The main difference is you just need to check if the id changed before fetching data. I also moved the initial fetch from the constructor to componentDidMount. Generally want to keep side-effects and setState calls out of the constructor, even when async.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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