0

I have a component(showing a list) that renders before the props (redux) are updated ( there is new item that is added to the list and should be displayed but it is not , unless the app is reloaded) . I wrote this to prevent this behaviour :

  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.data === nextProps.data) {
      return false;
    } else {
      return true;
    }
  }
  componentWillUpdate(prevProps){
      if(prevProps.data !== this.props.data){
         this.props.onFetchAction()
      }
  }

it makes the component update before the rendering , BUT on the console the onFetchAction() is fired non stop. How can I prevent this ????? any help would be apreciated .

random dreamer
  • 237
  • 1
  • 2
  • 14

3 Answers3

0

Probably by calling this.props.onFetchAction() You're updating props.data. What type of data you are storing in the this.props.data? If it is an object, you're making a comparison by references, not by data. That's why prevProps.data !== this.props.data will always be false and you will have an infinitive loop.

You can use isEqual (https://lodash.com/docs/4.17.14#isEqual) method of the lodash library. This method will check two objects by data in it, not by references. So the code will looks like: if (!isEqual(prevProps.data, this.props.data) { ... }.

Jaroslav
  • 1,863
  • 1
  • 12
  • 10
  • yes . data is an object. so what should I do to update the component on time AND not have this loop ??? – random dreamer Jul 10 '19 at 12:37
  • 1
    You can use `isEqual` (https://lodash.com/docs/4.17.14#isEqual) method of the `lodash` library. This method will check two objects by data in it, not by references. So the code will looks like: `if (!isEqual(prevProps.data, this.props.data) { ... }`. – Jaroslav Jul 11 '19 at 13:20
0

I believe the infinite loop is caused by onFetchAction. If onFetchAction is a function that causes this.props.data to update then this condition will always be true, hence the infinite loop.

 if(prevProps.data !== this.props.data){  //always true
     this.props.onFetchAction() //updates this.props.data
 }

You have to make sure that what ever is happening in onFetchAction it doesn't directly update this.props.data.

Response to comment.

If onFetchAction is something that updates this.props.data then I don't think that what you're doing would work. I would personally set onFetchAction in componentWillMount. And then when ever you need to update this.props.data invoke onFetchAction on whatever function you need it in.

componentWillMount() {
     this.props.onFetchAction()
}
Denz
  • 146
  • 4
0

this solves the problem :

shouldComponentUpdate(nextProps, nextState) {
    if (this.props.data === nextProps.data) {
      return false;
    } else {
      return true;
    }
  }
  componentDidUpdate(prevProps,prevState){
      if(prevProps.data.length !== this.props.data.length){
        this.props.onFetchAction()

      }
  }
random dreamer
  • 237
  • 1
  • 2
  • 14
  • `shouldComponentUpdate` would be more canonical as simply `shouldComponentUpdate(nextProps) { return this.props.data !== nextProps.data }` but if data is any sort of collection or object, e.g., not a string or a number etc, this comparison will not do what you think it does. – Dave Newton Sep 03 '19 at 21:57