'Toggle class on a mapped element in react
I am learning react and I have some doubts about changing the color onClick
How can I toggle the className of a <p>
element that is being clicked? At the moment clicking on one changes the color on everything.
I have read about passing a state on a parent element but at this point is getting a bit confusing and if someone could help me clarifying this would be nice.
Here's the code of my child element:
import "./Answer.scss";
function Answer(props) {
const getAnswers = [];
const correct_answer = props.correct_answer;
getAnswers.push(correct_answer);
for (let i = 0; i < props.incorrect_answers.length; i++) {
getAnswers.push(props.incorrect_answers[i]);
}
const [answers, setAnswer] = useState(getAnswers);
const [active, setActive] = useState(true);
const displayAnswers = answers.map((answer, index) => (
<p
className={active ? "answer" : "answer-active"}
key={index}
onClick={() => setActive((prevState) => !prevState)}
>
{answer.replace(/"|'/g, '"')}
</p>
));
return <div className="answer-box">{displayAnswers}</div>;
}
export default Answer;
And this is the parent:
import Answer from "../Answer/Answer";
function Questions(props) {
const questions = props.questions.map((question, index) => {
return (
<div className="question" key={index}>
<h2>{question.question.replace(/"|'/g, '"')}</h2>
<Answer
incorrect_answers={question.incorrect_answers}
correct_answer={question.correct_answer}
/>
<hr></hr>
</div>
);
});
return <div className="questions-container">{questions}</div>;
}
export default Questions;
Thanks everyone
Solution 1:[1]
Check this code.
const [answers, setAnswer] = useState(getAnswers);
const [active, setActive] = useState(true);
const displayAnswers = answers.map((answer, index) => (
<p
className={active ? "answer" : "answer-active"}
key={index}
onClick={() => setActive((prevState) => !prevState)}
>
{answer.replace(/"|'/g, '"')}
</p>
));
You are iterating your answers and updating the same state variable for each answer. It's like you are over-writing the updated values. Instead, you can make a separate state variable for each and every option. Based on the onClick
, you can update that specific answer state and use it in the code. Check the below code.
const AnswerText = ({ valid, index, answer }) => {
const [active, setActive] = useState(valid);
return (
<p
className={active ? "answer" : "answer-active"}
key={index}
onClick={() => setActive((prevState) => !prevState)}
>
{answer}
</p>
);
};
You can use the above component in the map and display your answers.
Attached is a sandbox for reference.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | mchowdam |