Possible leak in React.js axios fetching data and state update

86 views Asked by At

Everything is working with my cde but I have some very strange behavior that I cannot figure out. My returned promises start off with 1 or 1 and slowly get larger until after about 5 minutes it has over dozens of them. I am using this code...

    usePolling(function () {
        return Promise.resolve(getData())
      }, 4000);

The usePolling function...

function usePolling(fetcher, interval) {
    const [payload, setPayload] = useState(null);
    React.useEffect(function () {
        let timeoutId;
        function poll() {
            timeoutId = setTimeout(function () {
                // you must implement the error handling
                fetcher()
                    .then(function (resp) {
                        setPayload(resp)
                        poll();
                    })
            }, interval);
        }
        poll()      
        return function () {
            clearTimeout(timeoutId);
        }
    }, [fetcher, interval]);
    
    return payload;
  }

and the getData fecthing function...

const getData = () => {
    const value = Axios.post("http://localhost:3001/api/get-value",
    {user: userProp}).then((response) => {
        const recievedData = response.data;
        const dataValue = recievedData.map((val) => {
            return [val.value]
        })
        if (loading === true){
            setLoading(false);
        }
        setMoisture(parseInt(dataValue))
        console.log("sssssssssssssssss")
        return parseInt(dataValue);
    })
    return value
}

my log starts off like this... enter image description here

and after a few minutes is like this... enter image description here

What is causing this??

1

There are 1 answers

0
Justin Oberle On

I am not sure why no one could catch this but after completely taking apart my code and rebuilding, I found two main issue causing the render to get out of control. In the getData() function remove this...

    if (loading === true){
        setLoading(false);
    }
    setMoisture(parseInt(dataValue))

and instead of using state, use variables like this...

let loading = true;
let moisture;
moisture = usePolling(function () {
    return Promise.resolve(getData())
  }, 4000);
if (moisture !== null){
    loading = false
}

THATS IT!! This solved all of my issues. I am relatively new to react, and therefor state, but this makes sense. React re-renders whenever state changes. However I have asynchronous tasks running so even though my main page has fully rendered, I am still fetching data. Once that promise was fulfilled, the state changed and re-rendered. This caused renders to become very large because my app if rendering every n seconds the way it is set up. Hope this helps someone in the future.