Skip to content
Advertisement

How can I toggle styles (background-color to be specific) on multiple buttons with the same class (react.js)

So I have multiple setting buttons and I need them to individually toggle their background colors

here’s a simplified jsx example

   function App() {
      const [toggle, setToggle] = useState(false);

      document.querySelectorAll('.setting-tile').forEach(el => 
               el.addEventListener('click', setToggle(!toggle)));

      return (
       <div className='container'>
         <button className={`settings ${toggle? 'change-color' : ''}`}</button>

         <button className={`settings ${toggle? 'change-color' : ''}`}</button>

         <button className={`settings ${toggle? 'change-color' : ''}`}</button>

         <button className={`settings ${toggle? 'change-color' : ''}`}</button>
       </div>
      )
   }

CSS

.settings {
    background-color: white;
} 
.change-color {
    background-color: blue;
} 

but of course this won’t work because the style would be applied to all the buttons at once.

How can I identify which one is clicked and style that specific button without having to create states and event listeners for all the buttons?

Edit – In case this wasn’t clear, I’d like to be able to toggle all the buttons independently of each other.

Advertisement

Answer

I would do something as below … most of it is self explanatory 😉

const {useState} = React;

function App() {
  const [selected, setSelected] = useState("");
  
  const handleClick = (name) => {
    setSelected(name)
  }

  return (
    <div className="container">
      <Button name="one" selected={selected} onClick={handleClick}/>
      <Button name="two" selected={selected} onClick={handleClick}/>
      <Button name="three" selected={selected} onClick={handleClick}/>
      <Button name="four" selected={selected} onClick={handleClick}/>
    </div>
  );
}

function Button({name, onClick, selected}){
  return <button onClick={()=>onClick(name)} className={`settings ${name===selected ? "change-color" : ""}`}>{name}</button>
}

ReactDOM.createRoot(
    document.getElementById("root")
).render(
    <App/>
);
.settings {
    background-color: white;
} 
.change-color {
    background-color: blue;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

As per the comment below – one button toggle doesn’t un-toggle the other

const {useState} = React;

function App() {
  const [selected, setSelected] = useState({
    one : false,
    two : false,
    three : false,
    four : false
  });
  
  const handleClick = (name, isSelected) => {
    setSelected(prev=>({...prev,[name]: !isSelected}))
  }

  return (
    <div className="container">
      {Object.entries(selected).map(([btn, isSelected])=>(
        <Button key={btn} name={btn} isSelected={isSelected} onClick={handleClick}/>
      ))}
    </div>
  );
}

function Button({name, onClick, isSelected}){
  return <button onClick={()=>onClick(name, isSelected)} className={`settings ${isSelected ? "change-color" : ""}`}>{name}</button>
}

ReactDOM.createRoot(
    document.getElementById("root")
).render(
    <App/>
);
.settings {
    background-color: white;
} 
.change-color {
    background-color: blue;
} 
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement