Meadas
Meadas

Reputation: 101

Fetch method in useEffect is in infinite loop

I was getting the infinite loop of the code getting executed, but I couldn't find where the problem was. As I am new with react I sometimes struggle to see the problem. Could it be the dependency or that I forgot to close something off?

import {useCookies} from "react-cookie";
import React, {useEffect, useState} from "react";
import CircularProgress from "@mui/material/CircularProgress";
import {Navigate} from "react-router-dom";

const Date = () => {

    const [cookies] = useCookies(['XRSF-TOKEN']);
    const [loading, setloading] = useState(false);
    const [error, seterror] = useState(false);
    const [users, setusers] = useState([]);

    useEffect(() => {
        setloading(true);
        fetch("/allotherusers", {credentials: "include"})
            .then(response => response.text())
            .then(body => {
                if (body === '') {
                    return <Navigate to="/" />
                }
                else {
                    setusers(JSON.parse(body));
                }
                setloading(false);
            });
    }, [setusers, setloading])

    const userlist = users.map(user => {
        return (
            <div>
                <p> {user.firstname}</p>
                <button onClick={() => like(user, false)}>Like</button>
            </div>
        )
    });

    const like = async (likeduser, superlike) => {
        const likemodel = 
            {
            likeduser: likeduser,
            superlike: superlike

        }

        await fetch('/liked', {
            method: 'POST',
            headers: {
                'X-XSRF-TOKEN': cookies['XRSF-TOKEN'],
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(likemodel),
            credentials: 'include'
        });
    };


    return (
        <div>
            {userlist}
        </div>
    );

}
export default Date;

Here you see how the frontend is keep calling the API the request:

Backend api

Upvotes: 0

Views: 513

Answers (3)

Shlok Jadeja
Shlok Jadeja

Reputation: 64

inside of your effect function, when you do setusers(JSON.parse(body)) and setloading(false) you are updating userData to a new array. Even if all the items inside of that new array are exactly the same, the reference to the new userData array has changed, causing the dependencies of the effect to differ, triggering the function again -- ad infinitum.

One simple solution is to simply remove setusers from the dependency array. In this way, the useEffect function basically acts similar to componentDidMount in that it will trigger once and only once when the component first renders.

 useEffect(() => {
    setloading(true);
    fetch("/allotherusers", {credentials: "include"})
        .then(response => response.text())
        .then(body => {
            if (body === '') {
                return <Navigate to="/" />
            }
            else {
                setusers(JSON.parse(body));
            }
            setloading(false);
        });
}, [])

I think you should try this.!

Upvotes: 1

gnanasai Dachiraju
gnanasai Dachiraju

Reputation: 45

yes the problem is dependency,you are using callback(setState) as dependency ,you can keep and empty dependency since on the page render the api gets called and your state gets set.

 useEffect(() => {
         function fetchUsers(){
           setloading(true);
        fetch("/allotherusers", {credentials: "include"})
            .then(response => response.text())
            .then(body => {
                if (body === '') {
                    return <Navigate to="/" />
                }
                else {
                    setusers(JSON.parse(body));
                }
                setloading(false);
            });
}
      fetchUers();
    }, [])

Upvotes: 1

Sachila Ranawaka
Sachila Ranawaka

Reputation: 41407

Because both setusers, setloading is updating inside the useEffect which causes to fire the useEffect again. Just remove the side Effects from the useEffect array

 }, [])

Upvotes: 3

Related Questions