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 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *