The website gets stuck when I click next question

When I click the button my website stucks I dont know what is happening. I am using the while loop to not repeat the question in my quiz app. Help will be appreciated. The App and Questions function components are listed below. I am bringing my questions from an object array.

App.js

'''

import "./App.css";
import Questions from "./layout/Questions";

function App() {
  return (
    <div>
      <Questions />
    </div>
  );
}

export default App;


'''

Questions.js




import React, { useState } from "react";
import mcqs from "../data/mcqs";

const Questions = () => {
const handleButtonClick = () => {
 setquestionCounter(questionCounter + 1);
};
let randomQuestion = Math.floor(Math.random() * mcqs.length);
let [questionCounter, setquestionCounter] = useState(1);

if (questionCounter <= mcqs.length) {
 while (mcqs[randomQuestion].question === "999") {
   randomQuestion = Math.floor(Math.random() * mcqs.length);
 }
}
const string = mcqs[randomQuestion].question;
mcqs[randomQuestion].question = "999";
return (
 questionCounter <= mcqs.length && (
   <div className="questions">
     Q{questionCounter}:{string}
     <button onClick={handleButtonClick}>Next Question</button>
   </div>
 )
);
};

export default Questions;


1 answer

  • answered 2021-01-26 11:23 Yevgen Gorbunkov

    You seem to be triggering the infinite loop. By the way, doing the guesswork until getting the item that was not previously shown is not a good idea. You'd be much better off splicing the array of questions to show upon each iteration until it's empty:

    const { useState, useEffect } = React,
          { render } = ReactDOM,
          rootNode = document.getElementById('root')
          
    const questions = ['q1', 'q2', 'q3', 'q4', 'q5']
    
    const Question = ({question, pickQuestion}) => {
      return (
        <div>
          <div>{question}</div>
          <button onClick={pickQuestion}>Next Question</button>
        </div>
      )
    }
    
    const App = () => {
      const [currentQuestion, setCurrentQuestion] = useState(),
            [questionsToShow, setQuestionsToShow] = useState(questions),
            nextQuestion = () => {
              const questionsToShowCopy = [...questionsToShow],
                    nextQuestionIdx = 0|Math.random()*questionsToShowCopy.length
              setCurrentQuestion(questionsToShowCopy.splice(nextQuestionIdx,1))
              setQuestionsToShow(questionsToShowCopy)
            }
            
      useEffect(nextQuestion, [])
      
      return (
        <div>
          <Question 
            question={currentQuestion} 
            pickQuestion={nextQuestion} 
          />
        </div>
      )
    }
    
    render (
      <App />,
      rootNode
    )
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>