Quiz App in React

How to Make Quiz App in React

In this article, we will create a Quiz app in react. This Quiz game will be usual like other Quiz game. Here we will have some questions along with 4 options and scorecard. After answering all questions, the result will be appeared, and lastly we will have a button to restart the quiz.

So basically this is going to be a beginner-friendly project, so let’s make this project step-by-step.

Pre-requisites to Make Quiz App in React

  • Basic knowledge of ReactJS.
  • Basic knowledge of React hooks.
  • Basic knowledge of React props.
  • Good knowledge of React Components.

Building Skeleton for Quiz App in React

Let’s start with a little hard code, in return() statement, for questions, we have added a header tag for name of quiz, then another heading for score. Then, after we have hard coded our question and its options in the question card. And then lastly we have added result card where we have again hard coded correct answers and a restart button. This is just the beginning of the app, so it is right now hard coded, but we will improve this code after adding CSS.

return (
   <div className="App">
      {/* 1. Header  */}
      <h1>USA Quiz</h1>

      {/* 2. Current Score  */}
      <h2>Score: 0</h2>

      {/* 3. Show results or show the question game  */}
      {/* Final Results */}
      
        {/* 5. Question Card  */ }
        <div className="question-card">
          {/* Current Question  */}
          <h2>
            Question: 2 out of 5
          </h2>
          <h3 className="question-text">What is the capital of America?</h3>

          {/* List of possible answers  */}
          <ul>
            <li>New York City</li>
            <li>Boston</li>
            <li>Santa Fe</li>
            <li>Washington DC</li>
          </ul>
          
        </div>
        <div className="final-results">
          <h1>Final Results</h1>
          <h2>
            1 out of 5 correct - (
            20%)
          </h2>
          <button onClick={() => restartGame()}>Restart game</button>
        </div>
      
    </div>
  );
Quiz App in React

Adding CSS to Quiz App in React

Now, before making it dynamic, let’s add some CSS. We won’t go deeper with CSS because it’s not a big deal for us, nor it’s too hard to understand, so we just copy and paste it.

.App {
  text-align: center;
}

.question-card {
  /* Center the div  */
  margin: 0 auto;

  /* Dimensions  */
  width: 80%; /* Can be in percentage also. */
  height: auto;

  /* Visual  */
  background-color: gray;
  padding: 16px;
  border-radius: 16px;
  color: white;
  box-shadow: rgba(50, 50, 93, 0.25) 0px 30px 60px -12px,
    rgba(0, 0, 0, 0.3) 0px 18px 36px -18px;
}

ul {
  list-style: none;
}

li {
  margin-top: 8px;
  background-color: darkgray;
  padding: 16px;
  border: 3px solid white;
  border-radius: 20px;
  font-size: 20px;
}

.question-text {
  color: darkblue;
  font-size: 24px;
}

/* Final Results  */

.final-results {
  /* Center the div  */
  margin: 0 auto;

  /* Dimensions  */
  width: 50%; /* Can be in percentage also. */
  height: auto;
  margin-top: 64px;

  /* Visual  */
  background-color: gray;
  padding: 16px;
  border-radius: 16px;
  color: white;
  box-shadow: rgba(50, 50, 93, 0.25) 0px 30px 60px -12px,
    rgba(0, 0, 0, 0.3) 0px 18px 36px -18px;
}

button {
  background-color: red; /* Green */
  border: none;
  color: white;
  padding: 16px 24px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  font-weight: bold;

  border-radius: 24px;
}
Quiz App in React

Removing Result Part From Questions

Now let’s begin by removing the result part from the question screen, for that we have just added a state showResult with initial value false. Then we are using ternary condition on result and question card where if showResult is false then question card will be visible and if showResult is true then result card will show up.

const [showResults, setShowResults] = useState(false);


return (
    <div className="App">
       {/* 1. Header  */}
       <h1>USA Quiz</h1>
 
       {/* 2. Current Score  */}
       <h2>Score: 0</h2>
       
       {/* 3. Show results or show the question game  */}
       {/* Final Results */}
       {showResults? (
       <div className="final-results">
           <h1>Final Results</h1>
           <h2>
             1 out of 5 correct - (
             20%)
           </h2>
           <button onClick={() => restartGame()}>Restart game</button>
         </div>
       ) : (
         
         <div className="question-card">
           {/* Current Question  */}
           <h2>
             Question: 2 out of 5
           </h2>
           <h3 className="question-text">What is the capital of America?</h3>
 
           {/* List of possible answers  */}
           <ul>
             <li>New York City</li>
             <li>Boston</li>
             <li>Santa Fe</li>
             <li>Washington DC</li>
           </ul>
           
         </div>
         )}
     </div>
       
  );
Quiz App in React

Adding Questions Data

Now let’s add Questions, we have made a component named Questions.js component, we have added questions array in which we have added text property with a question and another property is options where we added 4 options with IDs, and also we have added isCorrect property with boolean values true and false.

const questions = [
    {
      text: "What is the capital of America?",
      options: [
        { id: 0, text: "New York City", isCorrect: false },
        { id: 1, text: "Boston", isCorrect: false },
        { id: 2, text: "Santa Fe", isCorrect: false },
        { id: 3, text: "Washington DC", isCorrect: true },
      ],
    },
    {
      text: "What year was the Constitution of America written?",
      options: [
        { id: 0, text: "1787", isCorrect: true },
        { id: 1, text: "1776", isCorrect: false },
        { id: 2, text: "1774", isCorrect: false },
        { id: 3, text: "1826", isCorrect: false },
      ],
    },
    {
      text: "Who was the second president of the US?",
      options: [
        { id: 0, text: "John Adams", isCorrect: true },
        { id: 1, text: "Paul Revere", isCorrect: false },
        { id: 2, text: "Thomas Jefferson", isCorrect: false },
        { id: 3, text: "Benjamin Franklin", isCorrect: false },
      ],
    },
    {
      text: "What is the largest state in the US?",
      options: [
        { id: 0, text: "California", isCorrect: false },
        { id: 1, text: "Alaska", isCorrect: true },
        { id: 2, text: "Texas", isCorrect: false },
        { id: 3, text: "Montana", isCorrect: false },
      ],
    },
    {
      text: "Which of the following countries DO NOT border the US?",
      options: [
        { id: 0, text: "Canada", isCorrect: false },
        { id: 1, text: "Russia", isCorrect: true },
        { id: 2, text: "Cuba", isCorrect: true },
        { id: 3, text: "Mexico", isCorrect: false },
      ],
    },
  ];

  export default questions;

Adding Questions

Now for questions, we have added a state for currentQuestion with initial 0 value and another state for score with initial 0 value. Then in return(), we have to modify score value with the value of state. Then in question card, we have added dynamic heading using <h2>Question: {currentQuestion + 1} out of {questions.length}</h2>.

After that, we have fetched the question using this questions[currentQuestion].text line of code. Now to fetch option, we have used map method to fetch every option, here we have used fetched the text of option using key value. And all options contain onClick event with a function call.

In this function, we have to increase the score value if isCorrect is true, and we will add another question by increasing the value of setCurrentQuestion. For example, if currentQuestion value is 1 then <h3 className="question-text">{questions[currentQuestion].text}</h3> this code will run and 1 question will be displayed, and if we increase the value of currentQuestion using setCurrentQuestion then we will get a 2nd question in that same div.

Basically, as soon we hit click on any option, then question will get changed till the last question.

const [currentQuestion, setCurrentQuestion] = useState(0);
  const [score, setScore] = useState(0);

const optionClicked = (isCorrect) => {
    // Increment the score
    if (isCorrect) {
      setScore(score + 1);
    }

    if (currentQuestion + 1 < questions.length) {
      setCurrentQuestion(currentQuestion + 1);
    } else {
      setShowResults(true);
    }
  };

return (
    <div className="App">
      {/* 1. Header  */}
      <h1>USA Quiz 🇺🇸</h1>

      {/* 2. Current Score  */}
      <h2>Score: {score}</h2>

      {/* 3. Show results or show the question game  */}
      {showResults ? (
        /* 4. Final Results */
        <div className="final-results">
          <h1>Final Results</h1>
          <h2>
            {score} out of {questions.length} correct - (
            20%)
          </h2>
          <button onClick={() => restartGame()}>Restart game</button>
        </div>
      ) : (
        /* 5. Question Card  */
        <div className="question-card">
          {/* Current Question  */}
          <h2>
            Question: {currentQuestion + 1} out of {questions.length}
          </h2>
          <h3 className="question-text">{questions[currentQuestion].text}</h3>

          {/* List of possible answers  */}
          <ul>
            {questions[currentQuestion].options.map((option) => {
              return (
                <li
                  key={option.id}
                  onClick={() => optionClicked(option.isCorrect)}
                >
                  {option.text}
                </li>
              );
            })}
          </ul>
        </div>
      )}
    </div>
  );
Quiz App in React

Calculating The Result

Now we are on the last stage of the quiz app, here in result part we have did some basic modification to get score value on the result div, and we have used (score / questions.length) * 100}% to calculate the percentage of result. Then we have added a function on restart button, in this function we have just reset all state values back to 0 and false.

 const restartGame = () => {
    setScore(0);
    setCurrentQuestion(0);
    setShowResults(false);
  };

<div className="final-results">
          <h1>Final Results</h1>
          <h2>
            {score} out of {questions.length} correct - (
            {(score / questions.length) * 100}%)
          </h2>
          <button onClick={() => restartGame()}>Restart game</button>
        </div>
Quiz App in React

Full Source Code to Make Quiz App in React

App.js

import React, { useState } from "react";
import "./App.css";

function App() {
  // Properties
  const [showResults, setShowResults] = useState(false);
  const [currentQuestion, setCurrentQuestion] = useState(0);
  const [score, setScore] = useState(0);


  // Helper Functions

  /* A possible answer was clicked */
  const optionClicked = (isCorrect) => {
    // Increment the score
    if (isCorrect) {
      setScore(score + 1);
    }

    if (currentQuestion + 1 < questions.length) {
      setCurrentQuestion(currentQuestion + 1);
    } else {
      setShowResults(true);
    }
  };

  /* Resets the game back to default */
  const restartGame = () => {
    setScore(0);
    setCurrentQuestion(0);
    setShowResults(false);
  };

  return (
    <div className="App">
      {/* 1. Header  */}
      <h1>USA Quiz 🇺🇸</h1>

      {/* 2. Current Score  */}
      <h2>Score: {score}</h2>

      {/* 3. Show results or show the question game  */}
      {showResults ? (
        /* 4. Final Results */
        <div className="final-results">
          <h1>Final Results</h1>
          <h2>
            {score} out of {questions.length} correct - (
            {(score / questions.length) * 100}%)
          </h2>
          <button onClick={() => restartGame()}>Restart game</button>
        </div>
      ) : (
        /* 5. Question Card  */
        <div className="question-card">
          {/* Current Question  */}
          <h2>
            Question: {currentQuestion + 1} out of {questions.length}
          </h2>
          <h3 className="question-text">{questions[currentQuestion].text}</h3>

          {/* List of possible answers  */}
          <ul>
            {questions[currentQuestion].options.map((option) => {
              return (
                <li
                  key={option.id}
                  onClick={() => optionClicked(option.isCorrect)}
                >
                  {option.text}
                </li>
              );
            })}
          </ul>
        </div>
      )}
    </div>
  );
}

export default App;

Questions.js

const questions = [
    {
      text: "What is the capital of America?",
      options: [
        { id: 0, text: "New York City", isCorrect: false },
        { id: 1, text: "Boston", isCorrect: false },
        { id: 2, text: "Santa Fe", isCorrect: false },
        { id: 3, text: "Washington DC", isCorrect: true },
      ],
    },
    {
      text: "What year was the Constitution of America written?",
      options: [
        { id: 0, text: "1787", isCorrect: true },
        { id: 1, text: "1776", isCorrect: false },
        { id: 2, text: "1774", isCorrect: false },
        { id: 3, text: "1826", isCorrect: false },
      ],
    },
    {
      text: "Who was the second president of the US?",
      options: [
        { id: 0, text: "John Adams", isCorrect: true },
        { id: 1, text: "Paul Revere", isCorrect: false },
        { id: 2, text: "Thomas Jefferson", isCorrect: false },
        { id: 3, text: "Benjamin Franklin", isCorrect: false },
      ],
    },
    {
      text: "What is the largest state in the US?",
      options: [
        { id: 0, text: "California", isCorrect: false },
        { id: 1, text: "Alaska", isCorrect: true },
        { id: 2, text: "Texas", isCorrect: false },
        { id: 3, text: "Montana", isCorrect: false },
      ],
    },
    {
      text: "Which of the following countries DO NOT border the US?",
      options: [
        { id: 0, text: "Canada", isCorrect: false },
        { id: 1, text: "Russia", isCorrect: true },
        { id: 2, text: "Cuba", isCorrect: true },
        { id: 3, text: "Mexico", isCorrect: false },
      ],
    },
  ];

  export default questions;

App.css

.App {
  text-align: center;
}

.question-card {
  /* Center the div  */
  margin: 0 auto;

  /* Dimensions  */
  width: 80%; /* Can be in percentage also. */
  height: auto;

  /* Visual  */
  background-color: gray;
  padding: 16px;
  border-radius: 16px;
  color: white;
  box-shadow: rgba(50, 50, 93, 0.25) 0px 30px 60px -12px,
    rgba(0, 0, 0, 0.3) 0px 18px 36px -18px;
}

ul {
  list-style: none;
}

li {
  margin-top: 8px;
  background-color: darkgray;
  padding: 16px;
  border: 3px solid white;
  border-radius: 20px;
  font-size: 20px;
}

.question-text {
  color: darkblue;
  font-size: 24px;
}

/* Final Results  */

.final-results {
  /* Center the div  */
  margin: 0 auto;

  /* Dimensions  */
  width: 50%; /* Can be in percentage also. */
  height: auto;
  margin-top: 64px;

  /* Visual  */
  background-color: gray;
  padding: 16px;
  border-radius: 16px;
  color: white;
  box-shadow: rgba(50, 50, 93, 0.25) 0px 30px 60px -12px,
    rgba(0, 0, 0, 0.3) 0px 18px 36px -18px;
}

button {
  background-color: red; /* Green */
  border: none;
  color: white;
  padding: 16px 24px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  font-weight: bold;

  border-radius: 24px;
}

Output Quiz App in React

Quiz App in React

Check out awesome video of Quiz App in React:

You may also like:

reactjsguru
reactjsguru
Articles: 66

Leave a Reply

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