polling api every x seconds with react

Eduardo Spaki picture Eduardo Spaki · Sep 10, 2017 · Viewed 33.7k times · Source

I have to monitoring some data update info on the screen each one or two seconds. The way I figured that was using this implementation:

componentDidMount() {
    this.timer = setInterval(()=> this.getItems(), 1000);
  }

  componentWillUnmount() {
    this.timer = null;
  }

  getItems() {
    fetch(this.getEndpoint('api url endpoint"))
        .then(result => result.json())
        .then(result => this.setState({ items: result }));
  }

Is this the correct approach?

Answer

Dangling Cruze picture Dangling Cruze · Aug 22, 2018

Well, since you have only an API and don't have control over it in order to change it to use sockets, the only way you have is to poll.

As per your polling is concerned, you're doing the decent approach. But there is one catch in your code above.

componentDidMount() {
  this.timer = setInterval(()=> this.getItems(), 1000);
}

componentWillUnmount() {
  this.timer = null; // here...
}

getItems() {
  fetch(this.getEndpoint('api url endpoint"))
    .then(result => result.json())
    .then(result => this.setState({ items: result }));
}

The issue here is that once your component unmounts, though the reference to interval that you stored in this.timer is set to null, it is not stopped yet. The interval will keep invoking the handler even after your component has been unmounted and will try to setState in a component which no longer exists.

To handle it properly use clearInterval(this.timer) first and then set this.timer = null.

Also, the fetch call is asynchronous, which might cause the same issue. Make it cancelable and cancel if any fetch is incomplete.

I hope this helps.