Saber
Saber

Reputation: 4719

useEffect infinite loop with axios

I'm stuck in an infinite loop in useEffect despite having tried the clean up function

I tried to pass [] and [usersDB] as the 2nd parameter of useEffect and it didn't work because [] makes it run only one time and it's not the behavior I'm looking for (I want it to run after each update)

 const ListUsers = () => {
  const [usersDB, setUsersDB] = useState([]);

  useEffect(() => {
    const getUsers = async () => {
      const response = await axios
        .get("http://localhost:4000/contacts")
        .catch((error) => console.log(error.resp));
      setUsersDB(response.data);
    };
    getUsers();
  }); 

  console.log(usersDB);

  return (
    <div>
        <div>
          {usersDB.map((user, index) => (
            <CardUsers key={user._id} user={user} />
          ))}
        </div>
    </div>
  );
};

export default ListUsers;

Upvotes: 0

Views: 1145

Answers (1)

Seth Lutske
Seth Lutske

Reputation: 10676

Every time the component renders, it runs your useEffect. Your useEffect calls setUsersDB, which updates state, which causes a rerender, which runs useEffect...

You can add an array of values at the end of useEffect which tells the useEffect to only run if any of the included values have changed. But if you add an empty array, it tells the useEffect to run only once, and never again, as there are no values that it depends on that have changed. You mention that you tried this, and that you want useEffect to run after each update. Each update of what? If there is some other value that is being updated elsewhere, and you want useEffect to be dependent on that value, then stick it in the dependency array.

  useEffect(() => {
    const getUsers = async () => {
      const response = await axios
        .get("http://localhost:4000/contacts")
        .catch((error) => console.log(error.resp));
      setUsersDB(response.data);
    };
    getUsers();
  }, [some updating value])

Upvotes: 1

Related Questions