How to create a timer in React with quiz
Create a Quiz application
Create a timer component -:
Create a timer component QstTimer.jsx for progress bar and define useEffect function.
export default function QstTimer({timeout, onTimeout}){
const [remainingTime , setRemainingTime ] = useState(timeout)
return <>
<progress id="question-time" max={timeout} value={remainingTime}/>
</>
}
Import timer component inside quiz component
import QstTimer from './QstTimer';
<QstTimer key={activeQuestionIndex} timeout={4000} onTimeout={handleskipAnswer}/>
Complete Code :
QstTimer.jsx
import { useState, useEffect } from 'react'
export default function QstTimer({timeout, onTimeout}){
const [remainingTime , setRemainingTime ] = useState(timeout)
useEffect(() =>{
console.log('timeout')
const timer = setTimeout(onTimeout, timeout);
return () => {
clearTimeout(timer);
}
}, [timeout, onTimeout])
useEffect(() => {
console.log("setInterval")
const interval = setInterval(() => {
setRemainingTime(prevremainingTime => prevremainingTime - 1000);
}, 1000);
return () => {
clearInterval(interval)
}
}, [])
return <>
<progress id="question-time" max={timeout} value={remainingTime}/>
</>
}
Quiz.jsx
import { useState, useCallback } from 'react'
import QUESTIONSLIST from './QuestionsList'
import QstTimer from './QstTimer';
export default function Quiz() {
const [userAnswer, setUserAnswer] = useState([]);
const activeQuestionIndex = userAnswer.length;
const isQuizComplete = activeQuestionIndex === QUESTIONSLIST.length;
const handleSelectedAnswer = useCallback(function handleSelectedAnswer(selectedAnswer){
setUserAnswer((prevans) => {
return [...prevans, selectedAnswer];
});
},[]);
const handleskipAnswer = useCallback(() => handleSelectedAnswer(null), [handleSelectedAnswer]);
if(isQuizComplete){
return <div id="summary">
<h1>Quiz Completed...</h1>
</div>
}
const shuffleAnswers = [...QUESTIONSLIST[activeQuestionIndex].answers];
shuffleAnswers.sort(() => Math.random() - 0.5);
return <>
<div id="quiz">
<h4>Select Answers</h4>
<div id="question">
<QstTimer key={activeQuestionIndex} timeout={4000} onTimeout={handleskipAnswer}/>
<h3>{QUESTIONSLIST[activeQuestionIndex].text}</h3>
<ul id="answer">
{/* {QUESTIONSLIST[activeQuestionIndex].answers.map((answer)=>( */}
{shuffleAnswers.map((answer)=>(
<li key={answer} className='answer'>
<button onClick={() => handleSelectedAnswer(answer)}>{answer}</button>
</li>
))}
</ul>
</div>
</div>
</>
}
Output
Keep Learning 🙂