Home > Mobile >  useEffect is calling API multiple time under component without any dependency
useEffect is calling API multiple time under component without any dependency

Time:12-26

I am beginners in React.Js

I don't know why useEffect is calling an API multiple time without any Dependency

If There any other Way to do it Please Suggest Me

Pages File : /pages/dashboard/speaking/[slug].js

} else if(slug == "repeat-sentence") {
    if (userData.role == "Admin") {
      return (<> <AdminRepeatSentence /> </>);           
    } else if(userData.role == "Teacher") {
      return (<> <TeacherRepeatSentece /> </>);
    } else if(userData.role == "Student") {
      return (<> <StudentRepeatSentece /> </>);            
    }

Component File : /components/dashboard/speaking/repeat-sentence.js

export function StudentRepeatSentece(params) {
    const [para, setPara] = useState();

    useEffect(() => {
         const handlePara = async () => {
              console.log(">>>>>>>>>>>>>>>fetching Have Been Start");
              const res = await fetch("/api/speaking/read-aloud");
              console.log(">>>>>> Fetch API <<<<<<<<<<");
              const data = await res.json();
              console.log(data);
              setData(data.para);
              console.log(">>>>>>>>> Convert Json <<<<<<<<");
         };

      handlePara();
   }, []);

   return (<> <SecondComponent myPara={para}/> </> );
}

Children Component

function SecondComponent({myPara}) {
        // Some Code Will Be Here
        useEffect(()=> {
                speak(myPara);
        }, [myPara]);

      retunr (<>someCode 
              {myPara} 
              Some Code
      </>);
}

CodePudding user response:

I thinks the problem is because of the setData(data.para) function being called on 10th line of StudentRepeatSentece component. The useEffect will surely run when the component is loaded but the setData() function uses useState hook, which makes sure that the component is re-rendered when the data stored inside para variable is changed, so it goes inside infinite loop of re-rendering the same component again and again. It is always a good practice to keep useEffect() clean by not using any other hooks like useState() inside useEffect(). However if required the workaround is:

export function StudentRepeatSentece(params) {
    const [para, setPara] = useState();
    const [assignValueToPara,setAssignValueToPara] = useState(true);

    useEffect(() => {
         const handlePara = async () => {
              console.log(">>>>>>>>>>>>>>>fetching Have Been Start");
              const res = await fetch("/api/speaking/read-aloud");
              console.log(">>>>>> Fetch API <<<<<<<<<<");
              const data = await res.json();
              console.log(data);
              setData(data.para);
              setIsValueAssignedToPara(false);
              console.log(">>>>>>>>> Convert Json <<<<<<<<");
         };

      handlePara();
   }, [AssignValueToPara]);

   return (<> <SecondComponent myPara={para}/> </> );
}

here you can create a boolean variable called assignValueToPara which keeps track of is value assigned to para variable or not. Add it as a dependency of useEffect. Initially the value of this variable will be true when the page loads, but as soon as the setPara() function is called on line number 10 this boolean will be also set to false and it will prevent your page from going inside this loop of re-rendering.

You can refer this blog for more details.

CodePudding user response:

If you are under <React.StrictMode>, it will rerender one more time the app.

May be it is.

  • Related