Search code examples
javascriptreactjsreact-routerreact-router-dom

How to keep the navigation active when accessing nesting navigation with React Router?


Is there a way which I can navigate to a nested route and keep the main navigation active?

For example this is the main navigation http://localhost:3000/#/tractian/assets-list and I get an active class from React Router:

enter image description here

But If I navigate to a nested route the class is removed: http://localhost:3000/#/tractian/assets-list/asset/1

enter image description here

How can I keep the class, shouldn't react-router understand that this is a nested route?

This is a sample of my code:

<HashRouter>
  <Layout>
    <Switch>
      <Route
        path={`${process.env.PUBLIC_URL}/assets-list`}
        exact
        component={AssetsList}
      />
      <Route
        path={`${process.env.PUBLIC_URL}/assets-list/asset/:id`}
        component={AssetComponent}
     />
    </Switch>
  </Layout>
</HashRouter>

NAVIGATION:

<ul className={classes["SideNavigation--navigation-items"]}>
  <h1>LOGO</h1>
  <li>
    <NavLink to={`${process.env.PUBLIC_URL}/`} exact>Overview</NavLink>
  </li>
  <li>
    <NavLink to={`${process.env.PUBLIC_URL}/assets-list` } exact>Ativos</NavLink>
  </li>
  <li>
    <NavLink to={`${process.env.PUBLIC_URL}/users-list`} exact>Usuários</NavLink>
  </li>
  <li>
    <NavLink to={`${process.env.PUBLIC_URL}/units-list`} exact>Unidades</NavLink>
  </li>
</ul>

NESTED NAVIGATION:
```jsx
<NavLink to={`${process.env.PUBLIC_URL}/assets-list/asset/${item.id}`}>
  TESTE
</NavLink>

I've tried to nest the route within the main one, but without success:

<Route
  path={`${process.env.PUBLIC_URL}/assets-list`}
  exact
  component={AssetsList}
>
  <Route
    path={`${process.env.PUBLIC_URL}/assets-list/asset/:id`}
    component={AssetComponent}
  />
</Route>

Solution

  • All the NavLink components are exactly matching the URL path, so if you are on a nested route the parent path no longer exactly matches.

    See v5 NavLink exact prop

    Remove the exact prop from the links that you want to also be matched as active when a sub-route is matched and rendered.

    Example:

    <ul className={classes["SideNavigation--navigation-items"]}>
      <h1>LOGO</h1>
      <li>
        <NavLink to={`${process.env.PUBLIC_URL}/`} exact>
          Overview
        </NavLink>
      </li>
      <li>
        {/* Not exact path matching, allow sub-route active matching */}
        <NavLink to={`${process.env.PUBLIC_URL}/assets-list`}>
          Ativos
        </NavLink>
      </li>
      <li>
        <NavLink to={`${process.env.PUBLIC_URL}/users-list`} exact>
          Usuários
        </NavLink>
      </li>
      <li>
        <NavLink to={`${process.env.PUBLIC_URL}/units-list`} exact>
          Unidades
        </NavLink>
      </li>
     </ul>
    
    <NavLink to={`${process.env.PUBLIC_URL}/assets-list/asset/${item.id}`}>
      TESTE
    </NavLink>
    

    navlink sub-route matching

    Edit how-to-keep-the-navigation-active-when-accessing-nesting-navigation-with-react-r