Hello! I am having some difficulties with the states of my quiz. Every time I click one of the three option buttons (from the JSX), the states [questionsAnswered] and [correctAnswers] get properly incremented, but only for a brief second before the page "refreshes" and the states return to their initial state. I need to stop these two states from returning to their initial states when changes are made to the page (specifically: when buttons are clicked). Is there any way to do this?
Here is my code:
import { useState, useContext, useEffect } from 'react'
import { Link } from 'react-router-dom'
import Logo from '../Components/Logo'
import Game_ById from '../Components/Game_ById';
import { QuizContext } from '../Contexts/QuizContext';
import IQuizContext from '../Interfaces/IQuizContext';
import '../Quiz.css';
const Quiz_Play = () => {
const {questions} = useContext(QuizContext) as IQuizContext; // get all questions from contexts
const [firstRender, setFirstRender] = useState(false);
useEffect(() => {
if(questions.length > 0){
generateRandomNumber()
nextQuestion()
setFirstRender(true);
}
return () => {
if (window.performance.navigation.type == 1) {
window.location.href = "/quiz"
}
};
}, [firstRender, questions]);
const [questionNum, setQuestionNum] = useState<number>(0)
const [questionText, setQuestionText] = useState<string>("")
const [questionImageId, setQuestionImageId] = useState<number | undefined>(0)
const [questionOptions, setQuestionOptions] = useState<string[]>([])
const [questionCorrect, setQuestionCorrect] = useState<string>("")
// these two states keep resetting back to 0 (initial state) when I click a button
const [questionsAnswered, setQuestionsAnswered] = useState<number>(0)
const [correctAnswers, setCorrectAnswers] = useState<number>(0)
const [random, setRandom] = useState<number>(0)
const generateRandomNumber = () => {
const rand = Math.floor(Math.random() * questions.length)
setRandom(rand)
}
const nextQuestion = () => {
generateRandomNumber()
const q = questions[random]
setQuestionNum(questionNum+1)
setQuestionImageId(q.gameId)
setQuestionText(q.question)
setQuestionOptions(q.options)
setQuestionCorrect(q.correct)
}
const chooseOption = (e : any) => {
console.log("current value is :" + e.currentTarget.value)
if(questionsAnswered != undefined){
setQuestionsAnswered(questionsAnswered+1)
}
if(e.currentTarget.value === questionCorrect){
setCorrectAnswers(correctAnswers+1)
}
}
return (
<div>
<Logo />
<div className="wrapper">
<h1 className="quizInfo_h1"> Question {questionNum} </h1>
<h2 className="quizQuestion_h2 text-align-center">{questionText}</h2>
<p className="correctCounter_p text-align-center no-margin "><span style={{color: '#f2c112'}}>{correctAnswers}</span>/{questionsAnswered}</p>
<div className="quizImage">
<Game_ById id={questionImageId}/>
</div>
</div>
<div className="quiz-options">
<form>
<button className="btn small-med-btn quiz-option-btn" id="option-1" onClick={chooseOption} value={questionOptions[0]}>{questionOptions[0]}</button>
<button className="btn small-med-btn quiz-option-btn" id="option-2" onClick={chooseOption} value={questionOptions[1]}>{questionOptions[1]}</button>
<button className="btn small-med-btn quiz-option-btn" id="option-3" onClick={chooseOption} value={questionOptions[2]}>{questionOptions[2]}</button>
</form>
</div>
<p style={{marginTop: 10, color:"rgba(255, 255, 255, 0.5)"}} className="text-align-center">
Don't want to play anymore? Feeling like a <Link to="/quiz" className="yellowlink">coward</Link>?
</p>
</div>
);
}
export default Quiz_Play;
I have read around online and I assume this could be fixed with the useRef hook, somehow? I have tried to implement something of the kind after seing some posts about it but I can't get it to work.
Thanks in advance to anyone taking the time to help. It's greatly appreciated
Also, let me know if you need me to provide additional information in order for you to assist.