Active link with React-Router?
Solution 1
This is an old, outdated answer for React Router v4
<Link>
no longer has the activeClassName
or activeStyle
properties. In react-router v4 you have to use <NavLink>
if you want to do conditional styling:
const Router = () => (
<BrowserRouter>
<div>
<Nav>
<NavLink exact={true} activeClassName='is-active' to='/'>Home</NavLink>
<NavLink activeClassName='is-active' to='/about'>About</NavLink>
</Nav>
<Match pattern='/' exactly component={Home} />
<Match pattern='/about' exactly component={About} />
<Miss component={NoMatch} />
</div>
</BrowserRouter>
)
I added an exact property to the home <NavLink>
, I'm fairly sure that without it, the home link would always be active since /
would match /about
and any other pages you have.
Solution 2
React Router v6:
Source: Active NavLink Classes with React Router
Now you can use the className
property which now accepts a function and passes an isActive
boolean property, like this:
<NavLink
to="users"
className={({ isActive }) => (isActive ? 'active' : 'inactive')}
>
Users
</NavLink>
You can also adding multiple classes too, since v6 is out:
<NavLink
to="users"
className={({ isActive }) =>
isActive ? 'bg-green-500 font-bold' : 'bg-red-500 font-thin'
}
>
Users
</NavLink>
Live demo: Active NavLink Classes with React Router
Solution 3
import { NavLink, useMatch, useResolvedPath } from 'react-router-dom';
const CustomNavLink = ({ to, title }) => {
let resolved = useResolvedPath(to);
let match = useMatch({ path: resolved.pathname, end: true });
return (
<NavLink to={to} className={`d-flex align-items-center py-2 px-4 ${match ? 'cta-btn' : 'c-n-b-link'}`} >
<span className='ms-1 f-w-600'>{title}</span>
</NavLink>
)
}
For React router V6
The above custom component will return a navlink that an active class can be activated whenever the path matches the given to
path.
Solution 4
In my case <NavLink />
automatically set active
class to items so I use the following method
myComponet.js
<ListItem component={NavLink} to="/somewhere" className="myactive" > something </ListItem>
myStyle.css
a.active.myactive {
// some styles
}
Related videos on Youtube
Saad
I love open source, teaching, and giving back to the community. Check out my GitHub if you want to see some of my work.
Updated on July 08, 2022Comments
-
Saad almost 2 years
I'm trying out React-Router (v4) and I'm having issues starting off the Nav to have one of the
Link
's beactive
. If I click on any of theLink
tags, then the active stuff starts working. However, I'd like for HomeLink
to be active as soon as the app starts since that is the component that loads at the/
route. Is there any way to do this?Here is my current code:
const Router = () => ( <BrowserRouter> <div> <Nav> <Link activeClassName='is-active' to='/'>Home</Link> {/* I want this to start off as active */} <Link activeClassName='is-active' to='/about'>About</Link> </Nav> <Match pattern='/' exactly component={Home} /> <Match pattern='/about' exactly component={About} /> <Miss component={NoMatch} /> </div> </BrowserRouter> )
-
wuno about 7 yearsI overlooked this answer today because I thought using NavLink was avoiding the problem at first glance. It is hard to find anywhere else that explains this. People need to upvote this answer because he is exactly right. you have to use NavLink. ALSO! the exact={true} is exactly right too. Otherwise the first link that renders will not re render when you click other links causing home to always be active. I wish I could upvote you 10 more times.
-
Wiktor Czajkowski almost 6 yearsIn case of nested routes, you might need to use
exact
for theNavLink
too. -
Brian Burns almost 6 yearsThank you for that link, @PetrAdam - was wondering why this wasn't working! (the solution is to wrap the
connect
call withwithRouter
). -
Pateta about 5 yearsTo avoid redux blocking a re-render you can provide the option
pure: false
to theconnect()
method. More information about a view no being updated: https://github.com/reduxjs/react-redux/blob/master/docs/troubleshooting.md -
Shamseer Ahammed about 4 yearsexact={true} on the home NavLink is a must, otherwise dashboard always stays active, very good explanation
-
StefanBob over 3 yearsexact={true} is needed for "/" route
-
iamafasha about 3 yearsJust wondering does this only work with BrowserRouter or even with Router
-
bastianwegge about 2 yearsI respect that you want to enhance this but the code you provided has no explanation and does not really work. This would leave someone searching for an answer at an unwanted state. Maybe there is a way to improve your answer?
-
bastianwegge about 2 yearsThank you for this answer! This component can also be used to resolve the "deep nested active" link problem :)
-
worc about 2 years@jayarjo as far i know, it's still valid for react-router 4, which was the current version at the time. it might help to pull that information to the top of the answer?
-
Live Software Developer almost 2 yearsHave just realized
Navlink
has an active class.active
so if you pass in your own class likemynavlinkclass
and targetmynavlinkclass.active
you can style the link when its active. This isNavlink
fromReact router dom V6