DEV Community

Tamilselvan K
Tamilselvan K

Posted on

Day-54 Building a Simple React Quiz App Using Context API

In this post, I’ll walk through how I created a basic quiz application using React. The goal of this app is to let users enter their name, take a multiple-choice quiz, and see their result at the end. I used React hooks and the Context API to manage global state like username, score, and gamestate.


Folder Structure

src/ ├── App.js ├── App.css ├── assets/ │ └── questions.json ├── components/ │ ├── User.js │ ├── Quiz.js │ └── Result.js 
Enter fullscreen mode Exit fullscreen mode

App.js

import logo from './logo.svg'; import './App.css'; import User from './components/User'; import Quiz from './components/Quiz'; import Result from './components/Result'; import { createContext, useEffect, useState } from 'react'; export const quizContext = createContext(); function App() { const [gamestate, setGamestate] = useState("users"); const [username, setUsername] = useState(""); const [score, setScore] = useState(0); return ( <div className="App"> <header className="App-header"> <quizContext.Provider value={{ gamestate, setGamestate, username, setUsername, score, setScore }}> {gamestate === 'users' && <User />} {gamestate === 'playing' && <Quiz />} {gamestate === 'result' && <Result />} </quizContext.Provider> </header> </div> ); } export default App; 
Enter fullscreen mode Exit fullscreen mode

User.js

import React, { useContext, useEffect, useRef } from 'react'; import { quizContext } from '../App'; function User() { const { gamestate, setGamestate, username, setUsername } = useContext(quizContext); const userRef = useRef(); useEffect(() => { userRef.current.focus(); }, []); function startPlaying() { setUsername(userRef.current.value); setGamestate("playing"); } return ( <div> <input type="text" placeholder='Enter useName' ref={userRef} /> <button onClick={startPlaying}>Start Quiz</button> </div> ); } export default User; 
Enter fullscreen mode Exit fullscreen mode

Quiz.js

import React, { useContext, useState } from 'react'; import questions from '../assets/questions.json'; import { quizContext } from '../App'; function Quiz() { const [currentQuestion, setCurrentQuestion] = useState(0); const [optionChosen, setOptionChosen] = useState(""); const { setGamestate, score, setScore } = useContext(quizContext); function next() { if (optionChosen === questions[currentQuestion]['answer']) { setScore(score + 1); } setCurrentQuestion(currentQuestion + 1); setOptionChosen(""); } function finish() { if (optionChosen === questions[currentQuestion]['answer']) { setScore(score + 1); } setGamestate("result"); } return ( <div> {questions[currentQuestion]['prompt']} { ['A', 'B', 'C', 'D'].map((opt) => ( <button onClick={() => setOptionChosen(`option${opt}`)}> {questions[currentQuestion][`option${opt}`]} </button> )) } { (questions.length - 1 === currentQuestion) ? (<button onClick={finish}>Finish</button>) : (<button onClick={next}>Next</button>) } </div> ); } export default Quiz; 
Enter fullscreen mode Exit fullscreen mode

Result.js

import React, { useContext } from 'react'; import { quizContext } from '../App'; import questions from '../assets/questions.json'; function Result() { const { setGamestate, setUsername, score, username, setScore } = useContext(quizContext); function restartQuiz() { setUsername(""); setScore(0); setGamestate("users"); } return ( <div> <h1>{`${username} scored ${score} out of ${questions.length}`}</h1> <button onClick={restartQuiz}>Restart Quiz</button> </div> ); } export default Result; 
Enter fullscreen mode Exit fullscreen mode

questions.json

[ { "prompt": "HTML stands for?", "optionA": "HyperText Markup Language", "optionB": "HyperText Mark Language", "optionC": "HyperText Markup Learn", "optionD": "Hyper Markup Language", "answer": "optionA" }, { "prompt": "JS stands for?", "optionA": "HyperText Markup Language", "optionB": "CSS", "optionC": "TypeScript", "optionD": "JavaScript", "answer": "optionD" }, { "prompt": "CSS stands for?", "optionA": "Cascading Style Sheets", "optionB": "Cascading Sheet Styles", "optionC": "Colorful Style Sheets", "optionD": "Computer Style Sheets", "answer": "optionA" }, { "prompt": "Which HTML element is used for the largest heading?", "optionA": "<h1>", "optionB": "<h2>", "optionC": "<h3>", "optionD": "<h4>", "answer": "optionA" }, { "prompt": "Which symbol is used to select classes in CSS?", "optionA": "#", "optionB": ".", "optionC": "*", "optionD": "&", "answer": "optionB" } ] 
Enter fullscreen mode Exit fullscreen mode

What I Learned

  • Using useRef for managing input focus
  • Conditional rendering based on state
  • Managing global state using Context API
  • Handling multiple components that rely on shared state
  • Loading data dynamically from a JSON file

Top comments (0)