0
\$\begingroup\$

I built a simple trivia with React from Vite that reads from an external JS file.

Here is the main code for the game:

import { useState } from "react";
import "./App.css";
import { questions } from "./assets/newquestions";
const App = () => {
 const [answer, setAnswer] = useState("");
 const [count, setCount] = useState(0);
 const styler = (choice) => {
 if (answer) {
 if (choice === questions[count].answer) {
 return { backgroundColor: "#00FF00", color: "#000000" };
 } else {
 return { backgroundColor: "#FF0000", color: "#000000" };
 }
 }
 };
 return (
 <>
 <h1>
 {count}) {questions[count].question}
 </h1>
 <div className="card">
 <button
 style={styler("A")}
 onClick={() => setAnswer("A")}
 disabled={answer !== ""}
 >
 <h2>A) {questions[count].A}</h2>
 </button>
 <button
 style={styler("B")}
 onClick={() => setAnswer("B")}
 disabled={answer !== ""}
 >
 <h2>B) {questions[count].B}</h2>
 </button>
 </div>
 <div className="card">
 <button
 style={styler("C")}
 onClick={() => setAnswer("C")}
 disabled={answer !== ""}
 >
 <h2>C) {questions[count].C}</h2>
 </button>
 <button
 style={styler("D")}
 onClick={() => setAnswer("D")}
 disabled={answer !== ""}
 >
 <h2>D) {questions[count].D}</h2>
 </button>
 </div>
 {answer ? (
 <button
 onClick={() => {
 setAnswer("");
 setCount(count + 1);
 }}
 >
 Next Question
 </button>
 ) : null}
 </>
 );
};
export default App;

Here is an small snippet of the question code:

export const questions = [
 {
 difficulty: "0",
 question: "Are you ready to start?",
 A: "Yes",
 B: "No",
 C: "No",
 D: "No",
 answer: "A",
 },
 {
 difficulty: "1",
 question: "Which artist painted the Mona Lisa?",
 A: "Picasso",
 B: "Leonardo Da Vinci",
 C: "Andy Warhol",
 D: "Aaron Van Kampen",
 answer: "B",
 },
...
Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges202 bronze badges
asked Sep 18, 2023 at 15:34
\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

With React, it's important to identify and separate what requires and what doesn't require state. In this scenario, the presentation of the questions and answers is mainly stateless while the selected question, and assessment of the answer are stateful. The one edge-case is indicating whether they answered correctly vs incorrectly.

My recommendations are:

  1. Redefine the data model to specify options as an Array instead of a through d, and the selected answer as the index from 0 to 3. This allows you to use a loop to render the options, which are identical and don't need to be repeated. This also allows you to generalize to more answers, for some questions, and potentially multiple answers in the future.
  2. Extract a presentational component that is stateless that displays the options. Bubble up an event for when an option is selected, pass in an optional selected attribute, and pass in additional selectedStyles attribute for showing the highlight when the answer is assessed.
  3. Consider using more semantic HTML elements such as input type="radio" to present the cards so that its more accessible.

I also noticed that you are using difficulty in the model but are not presenting it or using it in your assessment as well. I'd recommend removing that if its not being used, and if it is, consider changing it to a number.

answered Sep 20, 2023 at 7:46
\$\endgroup\$
2
\$\begingroup\$

Some suggestions after reviewing your code:

  1. Use Enums for Choices: Replace hardcoded "A", "B", "C", "D" with an enum for readability.

  2. DRY (Don't Repeat Yourself): Use a map function to generate button elements and make your code DRYer.

  3. Reset State: Reset the answer state when moving to the next question to avoid carrying over styles.

  4. Boundary Check: Add a condition to handle the end of the questions array.

  5. Semantic HTML: Replace <h2> inside buttons with span or div for semantic correctness.

  6. Simplify Styling Function: Move common styles like color: "#000000" to CSS to simplify the styler function.

answered Sep 19, 2023 at 23:32
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.