Active NavLink to parent element
If you abandon the NavLink
components altogether, you can create your own components that emulate the "activeness" of a NavLink
by using useHistory()
and useLocation()
from react-router-dom
.
Dashboard.js
const routeItems = [
{ route: '/route1', text: 'Route 1' },
{ route: '/route2', text: 'Route 2' },
];
<Router>
<NavBar routeItems={routeItems} />
</Router>
In NavBar.js
, we just need to check to see if the current active route is the same as the route for any individual item on the
NavBar.js
import { useHistory, useLocation } from 'react-router-dom';
const NavBar = (props) => {
const { routeItems } = props;
const history = useHistory();
const location = useLocation();
const navItems = routeItems.map((navItem) => {
return (
<div style={{
backgroundColor: navItem.route === location.pathname ? '#ADD8E6' : '',
}}
onClick={() => {
history.push(navItem.route);
}}
>
{navItem.text}
</div>
);
});
return (navItems);
};
export default NavBar;
Can be achived with Route component
<ul>
<Route path="/about">
{({ match }) => <li className={match ? 'active' : undefined}><Link to="/about">About</Link></li>
</Route>
</ul>
Reference: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Route.md#children-func
It doesn't seem like it is very easy to achieve. I used withRouter
HOC described in react router docs. It gives access to { match, location, history }
from props
inside components located outside of Routes
s. In the example I wrapped Nav
component to get location
and its pathname
. Here is the example code:
class Nav extends React.Component {
getNavLinkClass = (path) => {
return this.props.location.pathname === path ? 'active' : '';
}
render() {
return (
<nav>
<ul>
<li className={this.getNavLinkClass("/")}><NavLink exact to="/">Home</NavLink></li>
<li className={this.getNavLinkClass("/about")}><NavLink to="/about">About</NavLink></li>
</ul>
</nav>
)};
}
Nav = withRouter(Nav);
You will probably have to take care of params
in your routes (if you have any), to match properly. But you still have to match for each path you have in your NavLink
, which might not be pretty code. But the idea is that when the route is changed, Nav
is rerendered and correct li
is highlighted.
Here is a working example on codesandbox.