vishalkohli
vishalkohli

Reputation: 97

React Rest Call Infinite Loop Using Hooks

I am noticing that my component is stuck in an infinite loop. It keeps making the same rest call.

It is my understanding that useEffect hooks work similar to ComponentRender and ComponentUpdate lifecycle functions.

Also, I think what is happening is this but not able to fix it:

On render - > API called -> Updated Error state -> Component Updated -> UseEffect Hooked called again

Can you help me?

import React, { useState, useEffect } from "react";
import "./ResultsPage.css";
import Error from "../components/Error";

function Homepage() {
  let username = "test";

  const [error, setError] = useState({ exists: false, value: null });
  const [userData, setUserData] = useState(null);

  const getUsernameData = () => {
    fetch(`testAPI/${username}`)
      .then((response) => {
        if (response.status === 404) {
          return setError({ exists: true, value: response.status });
        }
        return response.json();
      })
      .then((json) => setUserData(json))
      .catch((error) => {
        setError({ active: true, type: 400 });
      });
  };
  useEffect(() => {
    getUsernameData();
  });

  return (
    <div className="Homepage">
      {error.exists && <Error error={error} username={username} />}
      {!error.exists && <h1>Error does not exist</h1>}
    </div>
  );
}

export default Homepage;

Upvotes: 0

Views: 772

Answers (2)

Brian Thompson
Brian Thompson

Reputation: 14355

useEffect will run on every render unless you tell it otherwise. Your effect has no dependency array, so it is running every render, triggering a re-render, and then starting over again infinitely.

You can tell the useEffect to only run once on mount by giving it an empty array:

useEffect(() => {
  getUsernameData();
}, []);

You can also tell it to only run when certain things change. Do this by adding the variables to the dependency array:

useEffect(() => {
  getUsernameData();
}, [variable_to_depend_on]);

Upvotes: 2

Chris Adams
Chris Adams

Reputation: 1454

Try changing...

useEffect(() => {
    getUsernameData();
});

to

useEffect(() => {
  getUsernameData();
}, []);

Upvotes: 1

Related Questions