I am practicing React useState hooks to make a quiz with a ten second timer per question.
Currently I am able to get the quiz questions from an API, set them to state, and render them. If a user clicks an answer, the question is removed from the array in state, the seconds in state is reset to 10 and the next question renders.
I am trying to get the timer to clear when there is nothing left in the array of questions in state. When I console.log(questions) in the startTimer function, it is an empty array, despite the same console.log showing the data in the userAnswer function? What am I missing here?
I've removed the referenced shuffle function to save space
function App() {
// State for trivia questions, time left, right/wrong count
const [questions, setQuestions] = useState([])
const [seconds, setSeconds] = useState(10);
const [correct, setCorrect] = useState(0);
const [incorrect, setIncorrect] = useState(0);
// Get data, set questions to state, start timer
const getQuestions = async () => {
let trivia = await axios.get("https://opentdb.com/api.php?amount=10&category=9&difficulty=easy&type=multiple")
trivia = trivia.data.results
trivia.forEach(result => {
result.answers = shuffle([...result.incorrect_answers, result.correct_answer])
})
setQuestions(trivia)
startTimer()
}
const startTimer = () => {
// Empty array here, but data at beginning of userAnswer
console.log(questions)
const interval = setInterval(() => {
// If less than 1 second, increment incorrect, splice current question from state, clear interval and start timer back at 10
setSeconds(time => {
if (time < 1) {
setIncorrect(wrong => wrong + 1)
setQuestions(q => {
q.splice(0,1)
return q;
})
clearInterval(interval);
startTimer()
return 10;
}
// I want this to hold the question data, but it is not
if (questions.length === 0) {
console.log("test")
}
// Else decrement seconds
return time - 1;
});
}, 1000);
}
// If answer is right, increment correct, else increment incorrect
// Splice current question from const questions
const userAnswer = (index) => {
// Shows array of questions here
console.log(questions)
if (questions[0].answers[index] === questions[0].correct_answer) {
setCorrect(correct => correct + 1)
} else {
setIncorrect(incorrect => incorrect + 1)
}
setQuestions(q => {
q.splice(0,1);
return q;
})
// Shows same array here despite splice in setQuestions above
console.log(questions)
setSeconds(10);
}
return (
<div>
<button onClick={() => getQuestions()}></button>
{questions.length > 0 &&
<div>
<Question question={questions[0].question} />
{questions[0].answers.map((answer, index) => (
<Answer
key={index}
answer={answer}
onClick={() => userAnswer(index)} />
))}
</div>
}
<p>{seconds}</p>
<p>Correct: {correct}</p>
<p>Incorrect: {incorrect}</p>
</div>
)
}
export default App;