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>