Design comparison
SolutionDesign
Solution retrospective
Is there a way to dynamically change classNames in react onClick? I used state for this, which seemed unnecessarily cumbersome, see below code (in components/MainCard.js):
//display "active" state of timeframe dynamically
const [dailyIsActive, setDailyIsActive] = useState(true);
const [weeklyIsActive, setWeeklyIsActive] = useState(false);
const [monthlyIsActive, setMonthlyIsActive] = useState(false);
const timeFrames = [
{ id: 1, type: "Daily", active: dailyIsActive },
{ id: 2, type: "Weekly", active: weeklyIsActive },
{ id: 3, type: "Monthly", active: monthlyIsActive },
];
const clickHandler = (event) => {
const clickedTimeframe = event.target.innerText.toLowerCase();
switch (clickedTimeframe) {
case "daily":
setDailyIsActive(true);
setWeeklyIsActive(false);
setMonthlyIsActive(false);
break;
case "weekly":
setWeeklyIsActive(true);
setDailyIsActive(false);
setMonthlyIsActive(false);
break;
case "monthly":
setMonthlyIsActive(true);
setDailyIsActive(false);
setWeeklyIsActive(false);
break;
default:
setDailyIsActive(true);
setWeeklyIsActive(false);
setMonthlyIsActive(false);
break;
}
};
<p
onClick={clickHandler.bind(this)}
key={timeFrame.id}
className={timeFrame.active ? `${styles.active}` : ""}
>
{timeFrame.type}
</p>
Community feedback
- @msunjiPosted over 2 years ago
Heya! So I tried tinkering a bit and this is the solution I've come up with:
In your
MainCard
component:- I made a new piece of state:
const [timeframe, setTimeframe] = useState('Daily');
- I added a data attribute called
data-timeframe
to yourp
element. It takestimeFrame.type
as a value. - For your
clickHandler
, I've removed the switch statement block and replaced it with:setTimeframe(event.target.getAttribute('data-timeframe'));
- Lastly, to toggle the active class, I've changed it up a bit to this:
className={timeFrame.type === timeframe ? `${styles.active}` : ''}
To sum it up, here's what's changed:
const [timeframe, setTimeframe] = useState('Daily'); // I cleaned up your timeframes array a bit and just removed the active property since I didn't need to use it const timeFrames = [ { id: 1, type: 'Daily' }, { id: 2, type: 'Weekly' }, { id: 3, type: 'Monthly' }, ]; const clickHandler = (event) => { const clickedTimeframe = event.target.innerText.toLowerCase(); setTimeframe(event.target.getAttribute('data-timeframe')); props.onChangeTimeframe(clickedTimeframe); };
and
<p onClick={clickHandler.bind(this)} key={timeFrame.id} data-timeframe={timeFrame.type} className={timeFrame.type === timeframe ? `${styles.active}` : ''} > {timeFrame.type} </p>
Not entirely sure if this is the most optimal way to solve this, but it's a start. Hope you find it helpful! By the way, your solution looks great! 👍
Marked as helpful0 - I made a new piece of state:
Please log in to post a comment
Log in with GitHubJoin our Discord community
Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!
Join our Discord