I need to set the active classname to multiple onclick items inside a .map
I have implemented by it only keeps track of current click active index
I need the list of active items that were clicked.
const [activeIndex, setActiveIndex] = useState(-1);
return (
<>
{data?.map((item, index) => {
return (
<Col
className={`mb-3 ${
index === activeIndex ? "selected" : "notselected"
}`}
key={item.id}
onClick={() => {
handleclick(item.id, index, item.name);
setActiveIndex(index);
}}
xs={6}
md={2}
>
<div
className={`common-cat-listener pop-cat-${item.id} all`}
>
<h4 className="cat-text py-4 px-3">{item.name}</h4>
</div>
</Col>
);
})}
</>
CodePudding user response:
Since you need to keep track of multiple items, the state for that can't be just a single number (unless you use prime number multiplication or something similarly absurd). Use an array of booleans instead.
const [activeIndicies, setActiveIndicies] = useState(() => data.map(() => false));
return (
<>
{data?.map((item, index) => {
return (
<Col
className={`mb-3 ${
activeIndicies[index] ? "selected" : "notselected"
}`}
key={item.id}
onClick={() => {
handleclick(item.id, index, item.name);
setActiveIndicies(activeIndicies.map((bool, j) => j === index ? true : bool);
}}
...
Tiny demo:
const App = () => {
const data = [1, 2, 3];
const [activeIndicies, setActiveIndicies] = React.useState(() => data.map(() => false));
return data.map((item, index) => {
return (
<span
className={activeIndicies[index] ? "selected" : "notselected"}
onClick={() => {
setActiveIndicies(activeIndicies.map((bool, j) => j === index ? true : bool));
}}
>{item}</span>
)
})
};
ReactDOM.render(<App />, document.querySelector('.react'));
.selected {
color: yellow;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>
CodePudding user response:
You seem to have and id for your items. I would assume they are all unique. If so, you could change your state for and array instead. The on Click method would then add the items.id inside the array and instead of doing
index === activeIndex
You could do :
activeIds.includes(item.id) ? // rest of code