18

I am trying to style my navigation by using the react activeClassName attribute. So far it works as expected, but there is a problem - my first nav links points to the root route(/). So even when on another URL it will register that URL (for example /skills) and root as active (so 2 menu items get styled).

Is there an easy workaround for this? Should I just define the Root route as something else (for example /home)?

My header:

import React, { PropTypes } from 'react';
import { Link, IndexLink } from 'react-router';

const Header = () => {
    return (
        <div className="header">
            <div className="headerImage"></div>
            <ul className="headerNav">
                <li className="headerNavLink"><Link to="/" activeClassName="activeLink">introduction</Link></li>
                <li className="headerNavLink"><Link to="/skills" activeClassName="activeLink">skills</Link></li>
                <li className="headerNavLink"><Link to="/portfolio" activeClassName="activeLink">portfolio</Link></li>
            </ul>
        </div>
    );
};

export default Header;

routes.js:

import React from 'react';
import { Route, IndexRoute } from 'react-router';
//Import app
import App from './components/App';
//Import pages
import IntroductionPage from './components/introduction/IntroductionPage';
import SkillsPage from './components/skills/SkillsPage';
import PortfolioPage from './components/portfolio/PortfolioPage';

//Define routes
export default (
    <Route path="/" component={App}>
        <IndexRoute component={IntroductionPage} />
        <Route path="skills" component={SkillsPage} />
        <Route path="portfolio" component={PortfolioPage} />
    </Route>
);

So to clarify, I would like my home route to not be active when on another route.

What am I doing wrong?

Thanks

Miha Šušteršič
  • 9,742
  • 25
  • 92
  • 163

5 Answers5

24

I'd like to reference the docs for React Router (react-router-dom, currently v5) and the sources. This is the up-to-date way to implement this:

exact: bool

When true, the active class/style will only be applied if the location is matched exactly.

<NavLink exact to="/profile">
  Profile
</NavLink>

Here is a real world working example:

<ul class="nav flex-column">
    <li class="nav-item">
      <NavLink className="nav-link" activeClassName="active" to="/" exact>Home</NavLink>
    </li>
    <li class="nav-item">
      <NavLink className="nav-link" activeClassName="active" to="/calendar">Calendar</NavLink>
    </li>
    <li class="nav-item">
      <NavLink className="nav-link" activeClassName="active" to="/page">Page</NavLink>
    </li>
</ul>
sr9yar
  • 4,850
  • 5
  • 53
  • 59
14

Just like also to share this if you use "react-router-dom": "4.1.1",

export const routes = <Index>
    <Route exact path='/' component={Home} />
    <Route path='/about' component={About} />
</Index>;

Then your navigation menu is

<NavLink exact={true} activeClassName='active' to="/">
   Home
</NavLink>
<NavLink activeClassName='active' to="/bout">
    About
</NavLink>

Just specify also the "exact={true}" props for the NavLink and it should work as expected.

Thanks, Hope this helps.

jayson.centeno
  • 835
  • 11
  • 15
  • 1
    Thanks, it helped. What I have learned is that 'exact' props in Route help in matching path before loading component while 'exact' props in NavLink help in matching path before applying 'active' class to tag. – Akash Kumar Seth Apr 18 '19 at 19:39
11

You can use <IndexLink> or set onlyActiveOnIndex prop for links that are not to be highlighted when their children paths are active:

<li className="headerNavLink"><IndexLink to="/" activeClassName="activeLink">introduction</IndexLink></li>

or

<li className="headerNavLink"><Link to="/" activeClassName="activeLink" onlyActiveOnIndex>introduction</Link></li>
Pawel Zubrycki
  • 2,703
  • 17
  • 26
11

This changed again in v6.

The prop exact has been replaced with end.

<NavLink end to="/profile">
  Profile
</NavLink>

Here is the React Router Dom docs reference

Jacopo Marrone
  • 77
  • 1
  • 10
manguy
  • 111
  • 1
  • 6
1

In react-router-dom ^4.0 there's no IndexRoute or IndexLink. Instead you need to specify the route path as exact and the child routes should be specified inside the <Route>'s component. See this answer for more details: https://stackoverflow.com/a/43311025/2713729

Janne Annala
  • 25,928
  • 8
  • 31
  • 41