2

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>
  );
};
1
  • This is because you are watching q, steps for useEffect and updating it within it. Which will cause useEffect to trigger again. You can remove it from dependency array Commented Apr 30, 2022 at 0:22

2 Answers 2

1

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]);
Sign up to request clarification or add additional context in comments.

4 Comments

I created a stackblitz, I'm still getting infinite loop stackblitz.com/edit/react-ts-caasck
Remove q as a dependency.
Your implementation appears way over-engineered imo. See my approach: stackblitz.com/edit/react-ts-duapfs?file=app.tsx
@Hyetigran did a good job of solving your problem. let us know if your problem still occurs.
0

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.

1 Comment

I created a stackblitz, I'm still getting infinite loop stackblitz.com/edit/react-ts-caasck?file=app.tsx

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.