Home > Software engineering >  Foreach loop runs forever ReactJS
Foreach loop runs forever ReactJS

Time:04-30

I'm trying to load QuestionsComponent components based on the No of questions received in the props;

Functionality works but application hangs after something, In console I could see the console.log(steps); getting logged infinite times.

What I'm doing wrong here ?

Please help

const DynamicForm: React.FC<any> = ({ questions }) => {
  const q: any = [];
  const [steps, setSetps] = useState([]);
  const [step, setStep] = useState(0);
  const refs = useRef<(HTMLDivElement | null)[]>([]);
  useEffect(() => {
    questions.forEach((question: any) => {
      q.push(QuestionsComponent);
    });
    setSetps(q);
    console.log(steps);

    scrollToComponent(refs.current[step], {
      offset: -100,
      align: 'top',
      duration: 1000,
    });
  }, [steps, questions, step, q]);

  return (
    <div>
      {steps
        .filter((_: any, index: any) => index <= step)
        .map((Step: any, index: any) => (
          <Step
            // eslint-disable-next-line
            key={index}
            question={questions[index]}
            domRef={(ref: any) => { refs.current[index] = ref; }}
            toPrev={() => {
              scrollToComponent(refs.current[index - 1]);
            }}
            toNext={() => {
              if (step === index   1) {
                scrollToComponent(refs.current[index   1]);
              }
              setStep(index   1);
            }}
            setStep={setStep}
            step={index}
          />
        ))}
    </div>
  );
};

CodePudding user response:

your useEffect hook has steps as a dependency which means it runs every time you call setSteps. You happen to call setSteps inside useEffect which renders the component continously and causes an infinite loop.

You could either remove steps as a dependency or add a conditional check:

 useEffect(() => {
    if(steps.length) return;
    questions.forEach((question: any) => {
      q.push(QuestionsComponent);
    });
    setSetps(q);
    console.log(steps);

    scrollToComponent(refs.current[step], {
      offset: -100,
      align: 'top',
      duration: 1000,
    });
  }, [steps, questions, step]);

CodePudding user response:

The resolve answer is like what @Hyetigran. I only add several tips to prevent something like this happen in the future.

  1. use ESLint with strict settings
  2. use Prettier to support the ESLint function
  3. install the plugin of both inside your IDE

With those things installed properly, you should get a warning when an infinite loop is happen in your code, and the suggestion would come out of the warning message.

  • Related