Home > OS >  Assign a classname to the selected element and the correct one in React
Assign a classname to the selected element and the correct one in React

Time:11-24

Assume I have a JSON-file that looks like this one:

{
  "data": [
    {
      "question": "What's 1 1",
      "answers": [
        {
          "text": "3",
          "correct": false
        },
        {
          "text": "2",
          "correct": true
        }
      ]
     }
   ]
}

In my code I am iterating over these answers and rendering a button for each. Each button also receives a click-handler like beneath. What I'd like to happen when you click a button, is that if it's the correct one, I should assign it a (correct) class. But if it's the wrong one, I will assign it another (wrong) class, but still show which was the correct one.

const handleClick = answer => {
  // How would I implement this logic?
 }

const App = ({ data }) => {

return (
  <div>
   {data.answers.map(answer => (
    <button onClick={() => handleClick(answer)}>{answer.text}</button>
   ))}
  </div>
 )
}

I tried to create a state variable to the button that was clicked. Then compare it against the parameter that was passed through the onclick handler.

CodePudding user response:

For Dynamic classname try this,

const App = ({ data }) => {

return (
 <div>
  {data.answers.map(answer => (
   <button classname={answer.correct ? 'correct-class' : 'wrong-class'`} onClick={() => handleClick(answer)}>{answer.text}</button>
  ))}
 </div>
)}

CodePudding user response:

You can maintain a selectedAnswer state that you set once you select an answer. You can then decide to show the correct class when mapping if the current answer's .correct property is true and the incorrect class if it is false, this class is stord in classType below. Since you only want to show these classes once you've selected an answer, you can conditionally add the class if:

  • You have selected an answer (ie selectedAnnswer has a value)

AND

  • Add the class if the currently mapped answer is correct OR the current answer is your selected answer

See example below:

const {useState} = React;
const App = ({ data }) => {
  const [selectedAnswer, setSelectedAnswer] = useState();
  const handleClick = answer => {
    setSelectedAnswer(answer);
  }

  return (
    <div>
     {data.answers.map(answer => {
        const classType = answer.correct ? "correct" : "incorrect";
        const showClass = selectedAnswer && (answer.correct || selectedAnswer === answer);
        return <button
          key={answer.text}
          className={showClass && classType}
          onClick={() => handleClick(answer)}>{answer.text}</button>
     })}
    </div>
  );
}


const obj = { "data": [ { "question": "What's 1 1", "answers": [ { "text": "3", "correct": false }, { "text": "2", "correct": true }, { "text": "1", "correct": false } ] } ] }
ReactDOM.createRoot(document.body).render(<App data={obj.data[0]} />);
.correct {background: lime;}
.incorrect {background: red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>

CodePudding user response:

 const App = ({ data }) => {

    return (
      <div>
       {data.answers.map(answer => (
        <button 
         className={`${answer.correct ? "correct" : "wrong"} other 
         classes `} 
         onClick={() => handleClick(answer)}>{answer.text}
        </button>
       ))}
      </div>
     )
    }

  • Related