Search code examples
reactjshttpinfinite-loop

React infinity loop when making HTTP calls using useEffect


I am trying to make 2 HTTTP calls inside a React component that will then call the setters for 2 properties that are defined using useState. I have followed what I thought was the correct way of doing so in order to prevent inifinite rerendering but this is still happening. Here is my code:

function Dashboard({ history = [] }) {
  const [teamInfo, setTeamInfo] = useState(null);
  const [survey, setSurvey] = useState(null);
  const [open, setOpen] = useState(false);
  const user = getUser();

  const getSurveyHandler = async () => {
    const surveyResponse = await getSurveys('standard');
    setSurvey(surveyResponse.data);
  };
  const getTeamInfoHandler = async () => {
    const teamInfoResponse = await getTeamInfo(user.teamId);
    setTeamInfo(teamInfoResponse);
  };     

  useEffect(() => {
    document.body.style.backgroundColor = '#f9fafb';

    getSurveyHandler();
    getTeamInfoHandler();
  }, [survey, teamInfo]);

As you can see, I have defined the functions outside of the useEffect and passed in the two state variables into the dependency array that will be checked to prevent infinite rerendering. Can anyone see why this is still happening?

Thanks


Solution

  • You are setting survey and teamInfo in your functions with a dependency on them in your useEffect.

    useEffect runs everytime a dependency changes. You are setting them, causing a rerender. Since they changed, the useEffect runs again, setting them again. The cycle continues.

    You need to remove those.

     useEffect(() => {
        document.body.style.backgroundColor = '#f9fafb';
    
        getSurveyHandler();
        getTeamInfoHandler();
      }, []);
    

    The only other thing recommended is to move async functions inside the useEffect unless you need to call them from other places in the component.

    useEffect(() => {
        const getSurveyHandler = async () => {
            const surveyResponse = await getSurveys('standard');
            setSurvey(surveyResponse.data);
        };
        const getTeamInfoHandler = async () => {
            const teamInfoResponse = await getTeamInfo(user.teamId);
            setTeamInfo(teamInfoResponse);
        };
        document.body.style.backgroundColor = '#f9fafb';
    
        getSurveyHandler();
        getTeamInfoHandler();
    }, []);