Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polling API every x seconds with react

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?

like image 568
Eduardo Spaki Avatar asked Sep 10 '17 12:09

Eduardo Spaki


People also ask

How polling is implemented in React?

It's a combo of setInterval() and clearInterval() , but all wrapped into one easy-to-implement Hook. All you need to do to get the Hook to work is supply it a function (the callback parameter) and an interval time (the delay ). Simple!

What makes Reactjs performance faster?

To optimize React rendering, you need to make sure that components receive only necessary props. It will let you control the CPU consumption and avoid over-rendering unnecessary features. The solution is to create a functional component that will collect all props and redistribute them to other components.

What is React restful API?

It is a medium that allows different applications to communicate programmatically with one another and return a response in real time. Roy Fielding defined REST in 2000 as an architectural style and methodology commonly used in the development of internet services, such as distributed hypermedia systems.


2 Answers

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.

like image 186
Dangling Cruze Avatar answered Oct 03 '22 21:10

Dangling Cruze


Although an old question it was the top result when I searched for React Polling and didn't have an answer that worked with Hooks.

// utils.js  import React, { useState, useEffect, useRef } from 'react';  export const useInterval = (callback, delay) => {    const savedCallback = useRef();    useEffect(() => {     savedCallback.current = callback;   }, [callback]);     useEffect(() => {     function tick() {       savedCallback.current();     }     if (delay !== null) {       const id = setInterval(tick, delay);       return () => clearInterval(id);     }   }, [delay]); } 

Source: https://overreacted.io/making-setinterval-declarative-with-react-hooks/

You can then just import and use.

// MyPage.js  import useInterval from '../utils';  const MyPage = () => {    useInterval(() => {     // put your interval code here.   }, 1000 * 10);    return <div>my page content</div>; } 
like image 25
GavKilbride Avatar answered Oct 03 '22 22:10

GavKilbride