'Missing isActive prop on NavLink of React Router v6
NavLink component of react-router-dom package supports adding extra logic for determining whether the link is active. At least this was supported in older version. Here is link to documentation: https://reactrouter.com/web/api/NavLink/isactive-func
Code snippet:
<NavLink
to="/events/123"
isActive={(match, location) => {
if (!match) {
return false;
}
// only consider an event active if its event id is an odd number
const eventID = parseInt(match.params.eventID);
return !isNaN(eventID) && eventID % 2 === 1;
}}
>
Event 123
</NavLink>
It seems like isActive property is not supported anymore in version 6. What are other options to achieve the same thing?
Solution 1:[1]
NavLink activeClassName prop does not exist anymore. With that prop you could pass a class for that specific Link to be modified with some CSS to show that it's become active, like this:
export function Header() {
return (
<header>
<ul>
<li>
<NavLink activeClassName="active" to="/about" />
</li>
<li>
<NavLink activeClassName="active" to="/profile" />
</li>
</ul>
</header>
)
}
With V6 you have to manually do that and you can by passing a function to the className prop we have on React, like this:
export function Header() {
return (
<header>
<ul>
<li>
<NavLink className={(navData) => navData.isActive ? "active" : "" } to="/about" />
</li>
<li>
<NavLink className={(navData) => navData.isActive ? "active" : "" } to="/profile" />
</li>
</ul>
</header>
)
}
Solution 2:[2]
From the source code of react-router-dom v6.0.0-beta.0, isActive now seems to be automatic.
/**
* A <Link> wrapper that knows if it's "active" or not.
*/
export const NavLink = React.forwardRef<HTMLAnchorElement, NavLinkProps>(
function NavLinkWithRef(
{
'aria-current': ariaCurrentProp = 'page',
activeClassName = 'active',
activeStyle,
caseSensitive = false,
className: classNameProp = '',
end = false,
style: styleProp,
to,
...rest
},
ref
) {
let location = useLocation();
let path = useResolvedPath(to);
let locationPathname = location.pathname;
let toPathname = path.pathname;
if (!caseSensitive) {
locationPathname = locationPathname.toLowerCase();
toPathname = toPathname.toLowerCase();
}
let isActive = end
? locationPathname === toPathname
: locationPathname.startsWith(toPathname);
let ariaCurrent = isActive ? ariaCurrentProp : undefined;
let className = [classNameProp, isActive ? activeClassName : null]
.filter(Boolean)
.join(' ');
let style = { ...styleProp, ...(isActive ? activeStyle : null) };
return (
<Link
{...rest}
aria-current={ariaCurrent}
className={className}
ref={ref}
style={style}
to={to}
/>
);
}
);
Here
let isActive = end
? locationPathname === toPathname
: locationPathname.startsWith(toPathname);
So to achieve the same you need to use your own style
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | ouflak |
| Solution 2 | Safi Nettah |
