Home > Blockchain >  Set acitve classname to multiple items in react js (map)
Set acitve classname to multiple items in react js (map)

Time:05-13

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
  • Related