I'm currently creating a multilevel sidebar menu in REACT and I want to dynamically add active class to parent <li>
when the current route is active.
The code below is how I do it for a single menu.
<Route
path={this.props.to}
exact={this.props.activeOnlyWhenExact}
children={({ match }) => (
<li className={match ? "active" : ""}>
<Link to={this.props.to} activeClassName="active">
<span className="sidebar-mini-icon">
<i className={this.props.icon}></i></span>
{this.props.label}
</Link>
</li>
)}
/>
Now I wonder how I do it with multilevel menu. My menu looks like this;
As you can see, only the menu has the active class. Here's my code for the multi level menu:
<Route
path={this.props.to}
exact={this.props.activeOnlyWhenExact}
children={({ match }) => (
<li>
<a data-toggle="collapse" href="#Collapse">
<span className="sidebar-mini-icon">
<i className={this.props.icon}></i>
</span>
<span className="sidebar-normal">
{this.props.name}
<b className="caret"></b>
</span>
</a>
<div class="collapse" id="Collapse">
<ul className="nav">
{this.props.children}
</ul>
</div>
</li>
)}
/>
I'm using React Router. Any help will be appreciated. Thank you.
The solution would depend on your route configuration. If you are using non-exact routes, the solution with NavLink would be the most applicable.
Example:
routes.jsx
<Route path="/parent/child-a">
<ChildA />
</Route>
<Route path="/parent/child-b">
<ChildB />
</Route>
<Route path="/parent">
<Parent />
</Route>
Using the above structure, /parent/child-a
would match two routes (/parent
and /parent/child-a
) and the activeClassName
prop on the NavLink
would be applied on both HTML element.
The "challenge" with the above structure is that you are going to render <Parent />
in all three cases.
This could be solved by using nested/child routes.
routes.jsx
<Route path="/parent">
<NestedRoutes />
</Route>
nestedRoutes.jsx
<Route path="/parent/child-a" exact>
<ChildA />
</Route>
<Route path="/parent/child-b" exact>
<ChildB />
</Route>
With the updated structure above, /parent/child-a
would match the top-level route (and as a result add the activeClassName
to your HTML element) and also match the child route and add the activeClassName
there too.
Note that if you need /parent
to also work as a route, you need to update your nested routes as follows:
nestedRoutes.jsx
<Route path="/parent" exact>
<Parent />
</Route>
From my experience, if you find yourself handling these cases manually through JavaScript or useLocation
you might want to revisit your route configuration. react-router
is an excellent library in its simplicity and will probably handle your case out of the box.
You can use React router's nav link
<NavLink to="/faq" activeClassName="selected">
FAQs
</NavLink>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With