如何使用React Hooks切换列表元素className并移除兄弟元素的active类
Got it, let's sort out this sidebar active class issue. The problem with your current code is two-fold:
- Only the Home link has an
onClickhandler to update the active state, so clicking About or Form does nothing. - You're storing a static string
'active'in state, which can't distinguish between different links—this would apply the class to all links if you added the handler to them, which isn't what you want.
Here are two solid solutions depending on your needs:
Solution 1: Manual Active State Management (No Route Sync)
If you just want the active class to update on click (regardless of the actual route), we'll track which link is active using a unique identifier for each item:
import { useState } from 'react'; import { Link } from 'react-router-dom'; const SideBar = () =>{ // Store the key of the active link instead of the class name const [activeLink, setActiveLink] = useState('home'); return ( <div className="sidebar"> <ul> <li> <Link onClick={() => setActiveLink('home')} className={activeLink === 'home' ? 'active' : ''} to="/" > Home </Link> </li> <li> <Link onClick={() => setActiveLink('about')} className={activeLink === 'about' ? 'active' : ''} to="/about" > About </Link> </li> <li> <Link onClick={() => setActiveLink('form')} className={activeLink === 'form' ? 'active' : ''} to="/form" > Form </Link> </li> </ul> </div> ) }
What changed:
- Instead of storing the class name, we store a unique key (
'home','about','form') for the active link. - Each
Linknow has anonClickhandler to set the corresponding key in state. - The
classNameprop uses a conditional: if the currentactiveLinkmatches the link's key, we add the'active'class; otherwise, it's empty.
Solution 2: Sync with React Router (Recommended)
If you want the active class to automatically update when the route changes (even if the user navigates via browser back/forward or another link), use React Router's useLocation hook to track the current path:
import { useLocation } from 'react-router-dom'; import { Link } from 'react-router-dom'; const SideBar = () =>{ const location = useLocation(); return ( <div className="sidebar"> <ul> <li> <Link className={location.pathname === '/' ? 'active' : ''} to="/" > Home </Link> </li> <li> <Link className={location.pathname === '/about' ? 'active' : ''} to="/about" > About </Link> </li> <li> <Link className={location.pathname === '/form' ? 'active' : ''} to="/form" > Form </Link> </li> </ul> </div> ) }
What changed:
- We removed the
useStateentirely because we don't need to manually track clicks—React Router tells us the current route. useLocationgives us access to the currentpathname, which we compare against eachLink'stovalue to determine if it should have the'active'class.- No need for
onClickhandlers here, since the active state is synced directly with the route.
This second approach is better for most cases because it ensures the sidebar always reflects the actual current page, even if navigation happens outside the sidebar itself.
内容的提问来源于stack exchange,提问作者malngaawy

