<Link to="/">Dashboard</Link>
<Link to="surveys">Surveys</Link>
ReactDOM.render((
<Router history={history}>
<Route component={App}>
<Route name="dashboard" path="/" component={Dashboard} />
<Route name="surveys" path="/surveys" component={Surveys} />
</Route>
</Router>
), document.getElementById('main'));
If I'm the dashboard route then just dashboard link gets active class. If I'm on surveys, dashboard and surveys link gets active class.
+1 got the same problem, my home page is always active
+1 I'm having this exact issue as well. mjackson noted that it was fixed in the master branch.
Just to note, if you pull down the master branch, it must be built with babel's support for (or another transpiler that supports) experimental ES7 export extensions.
You can perform the following to install it for your use:
npm install rackt/react-router#master
Then traverse to the root directory containing react-router to build it and run:
babel --stage 1 ./modules -d lib --ignore '__tests__'
That will install it into node_modules. Including --stage 1
when building it with babel will enable ES7 proposed features which are used.
Keep in mind that there are other caveats and undocumented changes to the API. A big one being that HashHistory, BrowserHistory, and MemoryHistory were moved into a separate npm module. You'll have to install that as well.
Check out this example to see how to use it.
Hmm.
Actually, I just attempted this using master. In my personal use case, it doesn't seem to be resolved.
<Router history={history}>
<Route component={app}>
<Route name="home" path="/" component={Home} />
<Route name="dashboard" path="dashboard" component={Dashboard} />
</Route>
</Router>
The "home" (/
) link is still marked as active when having traversed to the dashboard
path. I've seen various other issues that relate in some way.
This is pretty much a duplicate here: https://github.com/rackt/react-router/issues/1611
The following seem to be really related, but _not quite_ the same:
Check out this comment from ryanflorence containing a workaround.
@eXon & @drewhamlett
I tried all of the workarounds from the other issues that I linked to, but they didn't work. I seem to have fixed it in the for the master branch and in my case, which is similar to yours. But I haven't been able to run other tests for it, yet.
Gonna clarify what my train of thought was...
There are calls to some functions matchPattern()
and compilePattern()
which effectively return an empty string and empty arrays for checking the path when the it's the root path being sent in. I need to examine it a little further to really get it down, but essentially the patterns are chopped apart for things like splats (*
) and params (:someParam
) for all paths.
I fixed the issue by taking a look at these lines
When the pathname
passed into that function is "/", then PatternUtils.matchPattern()
returns a blank string as the remainingPathname
that's used down the line.
Once it gets to this point:
if (remainingPathname === '') {
return paramNames.every(function (paramName, index) {
return String(paramValues[index]) === String(activeParams[paramName]);
});
}
...it will always return true if paramNames
is empty and remainingPathname
is blank.
The JavaScript function every()
checks to see if every element of an array passes a test of a given function. The note to pay particular attention to is:
every acts like the "for all" quantifier in mathematics. In particular, for an empty array, it returns true.
So, again, if there are no parameters, then true
is returned.
I fixed the issue of the root route being active by changing the previous to this:
if (remainingPathname === '') {
// Change this:
// return paramNames.every(function (paramName, index) {
// to this:
return paramNames.length > 0 && paramNames.every(function (paramName, index) {
return String(paramValues[index]) === String(activeParams[paramName]);
});
}
So this seemed to fix it by short circuiting the every()
tests and returning false if there are no params and remainingPathname
is empty.
It _really_ feels like I'm working around the actual problem instead though. I'm pretty sure this isn't fixing it properly.
But yeah. Change that in lib/ActiveMixin.js
and it seems to work.
(PS Sorry for dumping so much out. This was _really_ bothering me, and I wanted to fix it, and I like to leave complete trains of thought.)
I think a PR with a failing test might help @mjackson get it fixed.
I'll definitely do that and try to help. Once I do some more digging and tested it, I'll submit one. I'm 85% sure that I've changed the wrong thing.
+1 just ran into this as well on beta3
solved it by changing around RouterContextMixin.js (Gist)
the PR I've sent a few days ago should fix that #1842
fixed in #1842
I am facing the same issue again.
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/" component={Wrapper}>
<IndexRoute path="/" component={Login}></IndexRoute>
<Route path="/registration" name="registration" component={Registration}></Route>
</Route>
</Router>
),
document.getElementById('app'));
My menu:
<li className="ui-component__primary-navigation-item">
<Link to='/' activeClassName="active">Login</Link>
</li>
<li className="ui-component__primary-navigation-item">
<Link to='/registration' activeClassName="active">Register</Link>
</li>
By default always I am getting active class on the first li
My current version is v2.8.1
Is there a regression? I'm experiencing this as well.
I have fixed and raised a pull request, waiting for reply now....
It seems there is an alternative component to Link for exactly this use-case.
<IndexLink to='/' activeClassName="active">Login</IndexLink>
works as expected
+1
@lefterisk, it's still broken if you use this.context.router.isActive(currentRoute)
In case anyone got the same issue as mine...
The link component wasn't re-render because no props was given to it :
App.js
render(props) {
return (
<div className={props.children.props.name}>
<Header path={props.children.props.path /*this props force re-render of header on each route change*/}/>
{props.children}
</div>
)
}
Header.js // nothing to do, component is re-render each time my route changes. The class active is properly applied.
const Header = () => (
<ul className="header">
<li><Link to="/" activeClassName="active">Home</Link></li>
<li><Link to="/contact" activeClassName="active">Contact</li>
</ul>
)
So everything works fine ;)
I've also having the same issue
my setup is using
react-router-v4
react-router-redux-5
@samuelmichaud setting activeClassName="active"
still not working for me
this is my setup - Header component
<Nav>
<LinkContainer to="/" activeClassName="active">
<NavItem eventKey={1}>Home</NavItem>
</LinkContainer>
<LinkContainer to="/about">
<NavItem eventKey={1}>About</NavItem>
</LinkContainer>
<LinkContainer to="/contact">
<NavItem eventKey={1}>Contact</NavItem>
</LinkContainer>
</Nav>
---- My Router Component
<ConnectedRouter history={history}>
<div>
<Header />
<Switch>
<Route path="/" component={Main} />
<Route path="/login" component={Login} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<PrivateRoute path="/profile" component={Profile}/>
</Switch>
</div>
</ConnectedRouter>
so for me following is working
<Nav>
<LinkContainer to="/" exact={true}>
<NavItem eventKey={1}>Home</NavItem>
</LinkContainer>
<LinkContainer to="/about">
<NavItem eventKey={1}>About</NavItem>
</LinkContainer>
<LinkContainer to="/contact">
<NavItem eventKey={1}>Contact</NavItem>
</LinkContainer>
</Nav>
@yasharma You need to use a
2 things to solve this:
withRouter
with your navigation component to trigger re-renderexact={true}
if using the built-in NavLink
component
Most helpful comment
It seems there is an alternative component to Link for exactly this use-case.
<IndexLink to='/' activeClassName="active">Login</IndexLink>
works as expected