Home > database >  Async/Await Function keeps triggering re-rendering
Async/Await Function keeps triggering re-rendering

Time:01-31

I having problem trying to get data from backend using axios. The function returns a Promise and whenever I call the function my component keeps rendering non-stop. Here is the code.

import { useState } from "react";
import Axios from "axios";

const DashBoard = () => {
  const [student, setStudent] = useState<{ [key: string]: string }[]>([]);
  const studentId = JSON.parse(localStorage.getItem("studentId") as string);
  const examResult: { [key: string]: string }[] = JSON.parse(
    localStorage.getItem("englishAnswers") as string
  );

  const getStudent = async () => {
    const { data } = await Axios.get(
      `http://localhost:3500/students/${studentId}`
    );
    setStudent(data);
  };
  getStudent(); //this line here keeps triggering re-render non stop;

CodePudding user response:

The function getStudent is being invoked on every render:

getStudent();

Since the operation within that function updates state, it triggers a re-render. So every render triggers a re-render, indefinitely.

If the intent is only to execute this on the first render, wrap it in a useEffect with an empty dependency array:

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

If studentId might change and you want to re-invoke this if it does, add that to the dependency array:

useEffect(() => {
  getStudent();
}, [studentId]);

You might take it a step further and put the function itself into a useCallback:

const getStudent = useCallback(async () => {
  const { data } = await Axios.get(
    `http://localhost:3500/students/${studentId}`
  );
  setStudent(data);
}, [studentId]);

This will only create a new instance of the function if/when studentId changes. Then the function itself can be the dependency for executing it:

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

CodePudding user response:

You need to wrap your getStudent() call in an useEffect hook. Because currently you are calling the getStudent function on each render, and as it triggers a setState method this leads into an infinite rendering.

useEffect(() => {
  const getStudent = async () => {
    const { data } = await Axios.get(
      `http://localhost:3500/students/${studentId}`
    );
    setStudent(data);
  };

  getStudent();
}, []);
  • Related