Introduction
In this tutorial, we will walk you through building a fun and interactive Quiz Website using React. This project is a great way for beginners to practice handling user input, managing state, and rendering dynamic content in React.
Project Overview
The Quiz Website allows users to answer multiple-choice questions and get instant feedback on their selections. At the end of the quiz, users are shown their scores along with the correct answers.
Features
Interactive Quiz: Users can answer questions and see their scores.
Real-Time Feedback: Immediate indication of whether the selected answer is correct or not.
Score Calculation: Keeps track of the score throughout the quiz.
Dynamic Content: Questions and options are rendered dynamically from a predefined list.
Technologies Used
React: For building the user interface and managing component states.
CSS: For styling the application.
JavaScript: For handling logic and quiz functionality.
Project Structure
The project is structured as follows:
├── public
├── src
│ ├── components
│ │ ├── Quiz.jsx
│ │ ├── Question.jsx
│ ├── App.jsx
│ ├── App.css
│ ├── index.js
│ └── index.css
├── package.json
└── README.md
Key Components
Quiz.jsx: Handles the quiz logic and score calculation.
Question.jsx: Displays individual questions and handles user input.
App.jsx: Manages the layout and renders the
Quiz
component.
Code Explanation
Quiz Component
The Quiz
component is responsible for rendering the questions, calculating the score, and handling quiz completion.
import { useEffect, useState } from "react";
import Result from "./Result";
import Question from "./Question";
const data = [
{
question: "What is the capital of France?",
options: ["Paris", "Berlin", "Madrid", "Rome"],
answer: "Paris",
},
{
question: "What is the capital of Germany?",
options: ["Berlin", "Munich", "Frankfurt", "Hamburg"],
answer: "Berlin",
},
{
question: "What is the capital of Spain?",
options: ["Madrid", "Barcelona", "Seville", "Valencia"],
answer: "Madrid",
},
{
question: "What is the capital of Italy?",
options: ["Rome", "Milan", "Naples", "Turin"],
answer: "Rome",
},
{
question: "What is the capital of the United Kingdom?",
options: ["London", "Manchester", "Liverpool", "Birmingham"],
answer: "London",
},
{
question: "What is the capital of Canada?",
options: ["Ottawa", "Toronto", "Vancouver", "Montreal"],
answer: "Ottawa",
},
{
question: "What is the capital of Australia?",
options: ["Canberra", "Sydney", "Melbourne", "Brisbane"],
answer: "Canberra",
},
{
question: "What is the capital of Japan?",
options: ["Tokyo", "Osaka", "Kyoto", "Nagoya"],
answer: "Tokyo",
},
{
question: "What is the capital of China?",
options: ["Beijing", "Shanghai", "Guangzhou", "Shenzhen"],
answer: "Beijing",
},
{
question: "What is the capital of Russia?",
options: ["Moscow", "Saint Petersburg", "Novosibirsk", "Yekaterinburg"],
answer: "Moscow",
},
{
question: "What is the capital of India?",
options: ["New Delhi", "Mumbai", "Bangalore", "Chennai"],
answer: "New Delhi",
},
{
question: "What is the capital of Brazil?",
options: ["Brasilia", "Rio de Janeiro", "Sao Paulo", "Salvador"],
answer: "Brasilia",
},
{
question: "What is the capital of Mexico?",
options: ["Mexico City", "Guadalajara", "Monterrey", "Tijuana"],
answer: "Mexico City",
},
{
question: "What is the capital of South Africa?",
options: ["Pretoria", "Johannesburg", "Cape Town", "Durban"],
answer: "Pretoria",
},
{
question: "What is the capital of Egypt?",
options: ["Cairo", "Alexandria", "Giza", "Luxor"],
answer: "Cairo",
},
{
question: "What is the capital of Turkey?",
options: ["Ankara", "Istanbul", "Izmir", "Antalya"],
answer: "Ankara",
},
{
question: "What is the capital of Argentina?",
options: ["Buenos Aires", "Cordoba", "Rosario", "Mendoza"],
answer: "Buenos Aires",
},
{
question: "What is the capital of Nigeria?",
options: ["Abuja", "Lagos", "Kano", "Ibadan"],
answer: "Abuja",
},
{
question: "What is the capital of Saudi Arabia?",
options: ["Riyadh", "Jeddah", "Mecca", "Medina"],
answer: "Riyadh",
},
{
question: "What is the capital of Indonesia?",
options: ["Jakarta", "Surabaya", "Bandung", "Medan"],
answer: "Jakarta",
},
{
question: "What is the capital of Thailand?",
options: ["Bangkok", "Chiang Mai", "Phuket", "Pattaya"],
answer: "Bangkok",
},
{
question: "What is the capital of Malaysia?",
options: ["Kuala Lumpur", "George Town", "Johor Bahru", "Malacca"],
answer: "Kuala Lumpur",
},
{
question: "What is the capital of the Philippines?",
options: ["Manila", "Cebu City", "Davao City", "Quezon City"],
answer: "Manila",
},
{
question: "What is the capital of Vietnam?",
options: ["Hanoi", "Ho Chi Minh City", "Da Nang", "Hai Phong"],
answer: "Hanoi",
},
{
question: "What is the capital of South Korea?",
options: ["Seoul", "Busan", "Incheon", "Daegu"],
answer: "Seoul",
},
];
const Quiz = () => {
const [currentQuestion, setCurrentQuestion] = useState(0);
const [score, setScore] = useState(0);
const [showResult, setShowResult] = useState(false);
const [timer, setTimer] = useState(30);
const [showNextButton, setShowNextButton] = useState(true);
useEffect(() => {
if (timer === 0) {
handleNext();
}
const timerId = setTimeout(() => setTimer(timer - 1), 1000);
return () => clearTimeout(timerId);
}, [timer]);
const handleAnswer = (selectedOption) => {
if (selectedOption === data[currentQuestion].answer) {
setScore(score + 1);
}
setShowNextButton(true); // Show the next button after answering
};
const handleNext = () => {
const nextQuestion = currentQuestion + 1;
if (nextQuestion < data.length) {
setCurrentQuestion(nextQuestion);
} else {
setShowResult(true);
}
setShowNextButton(true); // Hide the next button after moving to the next question
setTimer(30);
};
if (showResult) {
return <Result score={score} totalQuestion={data.length} />;
}
return (
<div className="quiz">
<div className="countandTime">
<div className="questionNumber">
Question : {currentQuestion + 1} <b>/</b> {data.length}
</div>
<div className="timer">Time left : {timer} seconds</div>
</div>
<Question
question={data[currentQuestion].question}
options={data[currentQuestion].options}
onAnswer={handleAnswer}
onNext={handleNext}
showNextButton={showNextButton}
/>
</div>
);
};
export default Quiz;
The Quiz
component manages the current question index and score. It also tracks when the quiz is finished, displaying the final score once all questions are answered.
Question Component
The Question
component handles the display of each question and allows the user to select an answer.
const Question = ({ question, options, onAnswer, onNext, showNextButton }) => {
return (
<div className="question">
<h2>{question}</h2>
{options.map((option, index) => (
<button className="option" key={index} onClick={() => onAnswer(option)}>
{option}
</button>
))}
{showNextButton && <button className="next" onClick={onNext}>Next </button>}
</div>
);
};
export default Question;
This component takes the data
prop, which includes the question and its options, and renders it dynamically. The handleAnswer
function processes the selected option.
App Component
The App
component manages the layout and renders the Quiz
component.
import Quiz from "./components/Quiz";
import "./App.css";
import logo from "./assets/images/quizlogo.png";
const App = () => {
return (
<div className="app">
<img className="logo" src={logo} alt="logo" />
<Quiz />
<p className="footer">Made with ❤️ by Abhishek Gurjar</p>
</div>
);
};
export default App;
This component structures the page with a header and footer, and the Quiz
component is rendered in the center.
Result Component
The Result
component is responsible for showing the user's quiz score after they submit their answers. It calculates the score by comparing the user's responses with the correct answers and provides feedback on how many questions were answered correctly.
const Result = ({ score, totalQuestion }) => {
return (
<div className='result'>
<h2>Quiz Complete</h2>
<p>Your score is {score} out of {totalQuestion}</p>
</div>
);
}
export default Result;
In this component, the score and total number of questions are passed as props. Based on the score, the component displays a message to the user, either praising them for getting all the answers correct or encouraging them to keep practicing. This dynamic feedback helps users understand their performance.
CSS Styling
The CSS ensures a clean and simple layout for the quiz. It styles the quiz components and provides user-friendly visuals.
* {
box-sizing: border-box;
}
body {
background-color: #cce2c2;
color: black;
margin: 0;
padding: 0;
font-family: sans-serif;
}
.app {
width: 100%;
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: column;
}
.app img {
margin: 50px;
}
/* Quiz */
.quiz {
display: flex;
flex-direction: column;
align-items: center;
width: 60%;
margin: 0 auto;
}
.countandTime {
display: flex;
align-items: center;
gap: 300px;
}
.questionNumber {
font-size: 20px;
background-color: #fec33d;
padding: 10px;
border-radius: 10px;
font-weight: bold;
}
.timer {
font-size: 18px;
background-color: #44b845;
color: white;
padding: 10px;
border-radius: 10px;
font-weight: bold;
}
/* Question */
.question {
margin-top: 20px;
}
.question h2 {
background-color: #eaf0e7;
width: 690px;
padding: 30px;
border-radius: 10px;
}
.question .option {
display: flex;
margin-block: 20px;
flex-direction: column;
align-items: flex-start;
background-color: #eaf0e7;
padding: 20px;
border-radius: 10px;
font-size: 18px;
width: 690px;
}
.question .next {
font-size: 25px;
color: white;
background-color: #35bd3a;
border: none;
padding: 10px;
width: 100px;
border-radius: 10px;
margin-left: 590px;
}
/* Result */
.result {
border-radius: 19px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
width: 500px;
height: 300px;
margin-top: 140px;
background-color: #35bd3a;
color: white;
}
.result h2{
font-size: 40px;
}
.result p{
font-size: 25px;
}
.footer {
margin: 40px;
}
The styling ensures that the layout is centered and provides hover effects on the quiz options, making it more interactive.
Installation and Usage
To get started with this project, clone the repository and install the dependencies:
git clone https://github.com/abhishekgurjar-in/quiz-website.git
cd quiz-website
npm install
npm start
This will start the development server, and the application will be running at http://localhost:3000
.
Live Demo
Check out the live demo of the Quiz Website here.
Conclusion
This Quiz Website is an excellent project for beginners looking to enhance their React skills. It provides an engaging way to practice managing state, rendering dynamic content, and handling user input.
Credits
- Inspiration: The project is inspired by the classic quiz games, combining fun and learning.
Author
Abhishek Gurjar is a web developer passionate about building interactive and engaging web applications. You can follow his work on GitHub.