I’ve a nextjs custom component that adds the locale before the pathname of the page when clicked and adds custom style for the active link..
here is the component
"use client";
import { useLocale } from "next-intl";
import Link from "next/link";
import { usePathname } from "next/navigation";
import React, { useEffect, useState } from "react";
export default function RoutingLink({
children,
href,
className,
activeClass
}: {
children: React.ReactNode;
href: string;
className?: string;
activeClass?: string;
}) {
const currentLocale = useLocale();
const pathname = usePathname();
const [isLinkActive, setIsLinkActive] = useState<boolean>(false);
useEffect(
() => {
if (pathname.slice(1) === href) {
setIsLinkActive(true);
}
() => {
setIsLinkActive(false);
};
},
[pathname]
);
function handleActiveClass() {
if (isLinkActive) {
if (activeClass) {
return activeClass;
} else {
return "text-primaryHover";
}
} else {
return "";
}
}
return (
<Link href={`/${currentLocale}/${href}`} className={`${className} ${handleActiveClass()}`}>
{children}
</Link>
);
}
the problem happened after I created a sidebar tab component *please have a look at the screenshot * , when I click at one link it becomes active and style changes but after I click at another one the previous link still have the active style as well.
I’ve tried to use useEffect() passing current pathname as dependency library to it, so that whenever the url is changed the active class should be changed and callback function should be called so that active style disappears from previous link.
2
Answers
It seems like the issue might be related to the way you’re setting and updating the
isLinkActive
state in youruseEffect
hook. The cleanup function in theuseEffect
seems to be incorrectly structured. Also, theuseEffect
might not be triggering as expected due to the waypathname
is compared tohref
.Let’s try a different approach. Instead of relying on
useEffect
for determining the active link, you could calculate the active status directly in the component by comparing thepathname
with thehref
prop.Here’s an updated version of your component that might resolve the issue:
This approach calculates the
isLinkActive
status directly in the component based on the comparison between the constructed link (/${currentLocale}/${href}
) and thepathname
. It then applies the active class accordingly without relying onuseEffect
. This should update the active class when the pathname changes.Give this a try and see if it resolves the issue with the active class not updating when the URL changes.
I think Tailwind won’t recall the function even your component re-renders. Moreover, if there are multiple RoutingLink on the same page, then when clicking on other link, the old RoutingLink is still mounted, means the callback function on useEffect won’t get called.
I would suggest you refactor a bit: