Home > Software design >  avoid loop on useEffect
avoid loop on useEffect

Time:08-14

I have a loop that will generate an Array with multiple datas. I do this loop in useEffect like this :

export const GeneratedProgram: React.FC<{}> = () => {
  const askedProgram = getFromLocalStorage("program");

  const [program, setProgram] = useState<any>();

  useEffect(() => {
    if (askedProgram) {
      for (let i = 0; i < askedProgram.length; i  ) {
        const muscles = Object.keys(askedProgram[i]);
        const numberOfExercices = Object.values(askedProgram[i]);

        const filerByMuscle: any = exercices.filter((exercice) => {
          return muscles.includes(exercice.id);
        });

        const randomExercices = filerByMuscle
          .sort(() => Math.random() - 0.5)
          .slice(0, numberOfExercices);

        setProgram(randomExercices);
      }
    }
  }, [askedProgram]);

The console tells me :

Warning: Maximum update depth exceeded.

I tried many ways to set my state differently but no success.

How can I set this new state and avoid the infinite re-render ?

CodePudding user response:

There are two reasons you are getting infinite loops.

1. You have program state variable inside the useEffect dependency array:

Since the useEffect you have updates program, having program in the dependency array cause the component to call setProgram infinitely. If you don't use program in your useEffect, you should take it off.

2. askedProgram gets a new reference every time.

Since in JS, [] === [] is false, every time component re-renders, the variable askedProgram changes reference, which causes useEffect to run again.

Try:

const askedProgram = useMemo(() => getFromLocalStorage("program"), [])
  • Related