0

I have an app that allows users to search Tweets about a particular topic. When searched, the Tweets will render on to a list. Once all the Tweets are rendered to the list I want the app to automatically load the new tweets on to the list w/o the user having to do anything. I am attempting to do this by having a setTimeOut function fetching from the API every minute but it just ends up being an infinite loop. How can i achieve this? Doing it with Redux.

List Component

  componentDidUpdate(prevProps, prevState) {
    if (prevProps.tweets !== this.props.tweets) {
      try {
        setInterval(async () => {
          this.props.fetchPosts(this.props.symbol);
        }, 3000);
      } catch (e) {
        console.log(e);
      }
    }
  }
j_nguyen
  • 119
  • 2
  • 11
  • i think it is better to share more code so its much easier to figure out what's the causing your problem. – albert Nov 11 '19 at 06:33

2 Answers2

0

Maybe your problem is with the if condition, if you are comparing two objects, the result in this case of prevProps.tweets !== this.props.tweets always be true, which will trigger a loop. In this case you have to compare in another way, like JSON.stringify(). Example:

let a = { attr1: 1, attr2: 2 };
let b = { attr1: 1, attr2: 2 };

// Comparing two objects with '==='
console.log(a === b) // false

// Comparing two objects with 'JSON.stringify()'
console.log(JSON.stringify(a) === JSON.stringify(b)) // true

Ref: Object comparison in JavaScript

leofalmeida
  • 323
  • 1
  • 10
  • The root problem of the question is the use of `componentDidUpdate`, not the way the props are compared. We can assume that `mapStateToProps` already recognizes the changed tweets correctly. – timotgl Nov 11 '19 at 14:40
  • In the docs of `componentDidUpdate`, they explicit and have an example, with fetch, and they say it must be wrapped in `if`. In this case, it has a `if`, but it is always true, so it is like I don't have a `if`, with that, they say that it can cause an infinite loop, that was occurring, according to the question. That's why I said that the problem can be the way he compared the `props`. – leofalmeida Nov 11 '19 at 15:34
  • In the React docs under https://reactjs.org/docs/react-component.html#componentdidupdate they use the same if condition and the `!==` check, so the comparison with `prevProps` and `props` would've been correct actually. – timotgl Nov 11 '19 at 16:32
  • But, they compare a userId, a attribute, not a entire object. Run the code in my answer or in your devtools, you will see the difference when you compare a variable with a primitive type and a object. – leofalmeida Nov 11 '19 at 16:34
  • Ah I see what you mean now, you're right. It would've triggered the same interval again and again. – timotgl Nov 11 '19 at 16:40
  • Yep, that's the problem I have tried to solve with the "right" comparison for objects haha :D – leofalmeida Nov 11 '19 at 16:45
0

You shouldn't use componentDidUpdate, and instead just let react-redux take care of putting the new posts into the component. Since this polling every minute runs forever, until you don't see the component anymore, componentDidMount and componentWillUnmount are your friends.

intervalID = null;

componentDidMount() {
    // Poll once every minute for new posts
    this.intervalID = setInterval(
        () => this.props.fetchPosts(this.props.symbol),
        60 * 60
    );
}

componentWillUnmount() {
    clearInterval(this.intervalID);
}
timotgl
  • 2,865
  • 1
  • 9
  • 19