Reputation: 82
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?
Upvotes: 1
Views: 113
Reputation: 3598
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>
Upvotes: 1