In my application I am using an ul and li tags and when one li is clicked the application is changing its background color with a class. I also wants to save the value of that li tag. I am trying to use setState hook with the class changing code but It seems its not working with each other. My code is
function store(e,q,a){
const allElements = document.querySelectorAll('*')
allElements.forEach(el => el.classList.remove('select'))
e.currentTarget.classList.add('select');
setCurquest({quest:q,ans:a});
}
<li onClick={(e) => {checkAns(e,quest.Qid,ans.Content)}}>{ans.Content}</li>
>Solution :
It looks like you’re trying to manage the state of a selected list item (li) in React while also directly manipulating the DOM to change the background color of the selected item. Direct DOM manipulation is generally not recommended in React because it can lead to inconsistencies between the actual DOM state and the React component state. Instead, you should use React’s state and rendering capabilities to achieve the desired behavior.
You can manage both the selection state and the background color change by using a state in your component to track the currently selected item. Then, you can conditionally apply a class to an item based on whether it is the selected item. This approach keeps everything within React’s declarative model.
Here’s an example of how you can modify your code to use React state for managing both the selection and the background color change:
import React, { useState } from 'react';
function MyComponent() {
const [currentSelection, setCurrentSelection] = useState(null);
// This function is called when an item is clicked
const handleItemClick = (e, questionId, answerContent) => {
// Update the current selection state with the clicked item's details
setCurrentSelection({ quest: questionId, ans: answerContent });
// You no longer need to manually manipulate classes on DOM elements
};
// Example data (replace with your actual data)
const questions = [
{ Qid: 1, answers: [{ Content: 'Answer 1' }, { Content: 'Answer 2' }] },
// Add more questions and answers here
];
return (
<ul>
{questions.map((quest) => (
quest.answers.map((ans) => (
<li
key={ans.Content} // Ensure you have a unique key for each list item
onClick={(e) => handleItemClick(e, quest.Qid, ans.Content)}
className={currentSelection && currentSelection.ans === ans.Content ? 'select' : ''}
>
{ans.Content}
</li>
))
))}
</ul>
);
}
In this example, setCurrentSelection is used to update the component’s state with the currently selected item. The className of each li element is conditionally set based on whether its content matches the currently selected item’s content. This eliminates the need for direct DOM manipulation and ensures that your component remains the single source of truth for its state and rendering.