I'm using React Router v4 and I have a case where on my navigation links, I want to enable the active
className to the NavLink
parent element, not the NavLink
itself.
Is there a way to access the path (match
) even though I'm not inside the Switch
element?
Or do I have to keep state? Because I'm feeling it's kinda missing the idea of router.
Here's my example, I want to apply the active
className to li
element not NavLink
:
const { HashRouter, Switch, Route, Link, NavLink, } = ReactRouterDOM const About = () => ( <article> My name is Moshe and I'm learning React and React Router v4. </article> ); const Page = () => ( <Switch> <Route exact path='/' render={() => <h1>Welcome!</h1>} /> <Route path='/about' component={About}/> </Switch> ); const Nav = () => ( <nav> <ul> <li><NavLink exact to="/">Home</NavLink></li> <li><NavLink to="/about">About</NavLink></li> </ul> </nav> ); class App extends React.Component { render() { return ( <div> <Nav /> <Page /> </div> ); } } ReactDOM.render(( <HashRouter> <App /> </HashRouter>), document.querySelector("#app"));
https://codepen.io/moshem/pen/ypzmQX
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.
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
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