2

Yo there! Back at it again with a noob question!

So I'm fetching data from an API to render a quizz app and I'm struggling with a simple(I think) function : I have an array containing 4 answers. This array renders 4 divs (so my answers can each have an individual div). I'd like to change the color of the clicked div so I can verify if the clicked div is the good answer later on.

Problem is when I click, the whole array of answers (the 4 divs) are all changing color.

How can I achieve that?

I've done something like that to the divs I'm rendering :

const [on, setOn] = React.useState(false);

  function toggle() {
    setOn((prevOn) => !prevOn);
  }

  const styles = {
    backgroundColor: on ? "#D6DBF5" : "transparent",
  };

I'll provide the whole code of the component and the API link I'm using at the end of the post so if needed you can see how I render the whole thing.

Maybe it's cause the API lacks an "on" value for its objects? I've tried to assign a boolean value to each of the items but I couldn't seem to make it work.

Thanks in advance for your help!

The whole component :

import React from "react";
import { useRef } from "react";

export default function Quizz(props) {
  const [on, setOn] = React.useState(false);

  function toggle() {
    setOn((prevOn) => !prevOn);
  }

  const styles = {
    backgroundColor: on ? "#D6DBF5" : "transparent",
  };

  function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
      let j = Math.floor(Math.random() * (i + 1));
      let temp = array[i];
      array[i] = array[j];
      array[j] = temp;
    }
    return array;
  }

  let answers = props.incorrect_answers;

  const ref = useRef(false);
  if (!ref.current) {
    answers.push(props.correct_answer);

    shuffleArray(answers);
    ref.current = true;
  }

  const cards = answers.map((answer, key) => (
    <div key={key} className="individuals" onClick={toggle} style={styles}>
      {answer}
    </div>
  ));

  console.log(answers);
  console.log(props.correct_answer);

  return (
    <div className="questions">
      <div>
        <h2>{props.question}</h2>
      </div>
      <div className="individuals__container">{cards}</div>
      <hr />
    </div>
  );
}

The API link I'm using : "https://opentdb.com/api.php?amount=5&category=27&type=multiple"

1 Answer 1

1

Since your answers are unique in every quizz, you can use them as id, and instead of keeping a boolean value in the state, you can keep the selected answer in the state, and when you want render your JSX you can check the state is the same as current answer or not, if yes then you can change it's background like this:

function Quizz(props) {
  const [activeAnswer, setActiveAnswer] = React.useState('');
  function toggle(answer) {
    setActiveAnswer(answer);
  }
  ...
  const cards = answers.map((answer, key) => (
    <div key={key}
         className="individuals"
         onClick={()=> toggle(answer)}
         style={{background: answer == activeAnswer ? "#D6DBF5" : "transparent" }}>
         {answer}
    </div>
));
  ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Oh my! Thanks for your quick answer man! It indeed works and it was as simple as I thought haha, I knew I did something a bit silly but I couldn't figure out what ! Thanks again and have a nice day!

Your Answer

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.