I am currently learning React and I have a functional component for a menu. When a value is clicked I want to add the ‘choice-selected’ class to visually show it has been selected and make sure no other button has the class. Is there a way to create this behavior without creating a separate useState hook for every selection?
Here is my code:
function SortMenu(props){ const [clickedDay, setClickedDay] = useState(''); const [clickedMonth, setClickedMonth] = useState(''); const [clickedYear, setClickedYear] = useState(''); const choice = (value) =>{ props.setSort(value); switch(value){ case 'day': setClickedDay( (prevVal) => { prevVal =='' ? setClickedDay('choice-selected'): setClickedDay(''); setClickedMonth(''); setClickedYear(''); }); break; case 'month': setClickedMonth( (prevVal) => { prevVal =='' ? setClickedMonth('choice-selected'): setClickedMonth(''); setClickedDay(''); setClickedYear(''); }) break; case 'year': setClickedYear( (prevVal) => { prevVal =='' ? setClickedYear('choice-selected'): setClickedYear(''); setClickedDay(''); setClickedMonth(''); }) break; } } return( <nav className="sortmenu"> <div className={`${clickedDay} choice`} onClick={() => {choice("day");}}>Day</div> <div className={`${clickedMonth} choice`} onClick={() => {choice("month")}}>Month</div> <div className={`${clickedYear} choice`} onClick={() => {choice("year")}}>Year</div> </nav> ) }
Currently my code does work, but if I need to add more choices I have to not only add another case, but add the new choices in the existing cases as well. I am wondering if there is an easier or better way to implement this behavior?
Advertisement
Answer
Here is a working example of the solution I described in the comments.
const { useState } = React; const SortMenu = () => { const [clickedChoice, setClickedChoice] = useState(''); const choice = (value) => { setClickedChoice(prev => prev === value ? '' : value); }; return ( <nav> <div className={`${clickedChoice === 'day' ? 'choice-selected' : ''} choice`} onClick={() => choice('day')} >Day</div> <div className={`${clickedChoice === 'month' ? 'choice-selected' : ''} choice`} onClick={() => choice('month')} >Month</div> <div className={`${clickedChoice === 'year' ? 'choice-selected' : ''} choice`} onClick={() => choice('year')} >Year</div> </nav> ) } ReactDOM.render(<SortMenu/>, document.querySelector('#root'));
.choice { border: 1px solid black; padding: 2px; } .choice-selected { background-color: pink; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> Click an option to de/select it. <div id="root"></div>