I know how to 'highlight' an active link in React.js, I do it like this:
<Link
className={splitted[1] === 'Details'
? "bg-red-800 rounded-full hover:text-white"
: "hover:bg-blue-800 rounded-full hover:text-white"
}
key={'xxx'}
to={`/Details/${id}`}
>
This is my link
</Link>
(ok, maybe a bit overkill, but it works)
But I have problems doing the same with a bunch of links that are rendered via a mapping. I try to do the same but it doesn't work at all. What is wrong in the code below?
const renderedLinks = links.map((link) => {
return (
<Link
className={splitted[1] === `${link.path}`
? "bg-red-800 rounded-full hover:text-white"
: "hover:bg-blue-800 rounded-full hover:text-white"
}
key={link.label}
to={link.path}
>
{link.label}
</Link>
)
});
So, how do I get the variable link.path
into this?
Links are generated by this:
const links = [
{ label: 'Details', path: '/Details' },
...
]
And splitted
is is the first path of the pathname
obtained by useLocation
.
I am using react-router-dom@6
.
Instead of the Link
component it would be better to use the NavLink
component as it has logic baked-in to handle matching an active link to the current URL path. Use the className
callback to access the isActive
prop and conditionally apply the appropriate CSS classes.
Example:
<Link
key={'xxx'}
to={`/Details/${id}`}
className={({ isActive }) =>
[
"rounded-full hover:text-white",
isActive ? "bg-red-800" : "hover:bg-blue-800"
].join(" ")
}
>
This is my link
</Link>
const renderedLinks = links.map((link) => (
<Link
key={link.path}
to={link.path}
className={({ isActive }) =>
[
"rounded-full hover:text-white",
isActive ? "bg-red-800" : "hover:bg-blue-800"
].join(" ")
}
>
{link.label}
</Link>
));
If you render links to both parent and child/descendent paths, i.e. "/details"
and "/details/specificDetails"
then you can also specify the end
prop on the NavLink
so the active link is matched by the end of the path.
If the
end
prop is used, it will ensure this component isn't matched as "active" when its descendant paths are matched. For example, to render a link that is only active at the website root and not any other URLs, you can use:<NavLink to="/" end> Home </NavLink>
Applied to your code:
const renderedLinks = links.map((link) => (
<Link
key={link.path}
to={link.path}
className={({ isActive }) =>
[
"rounded-full hover:text-white",
isActive ? "bg-red-800" : "hover:bg-blue-800"
].join(" ")
}
end // <--
>
{link.label}
</Link>
));