javascriptreactjstypescriptnext.js

Reloading with frequent clicking on the Profile button


When I click on the profile link multiple times, the page keeps reloading and sending lots of requests before finally redirecting to the profile. How can I prevent the page from reloading and make it instantly follow the link??
I tried switch <a> on <Link> next js, but i'm not sure if CSS styling will be affected.

const NavProfile = () => (
        <>
            <NavbarLink href="/profile">
                <UIIcon
                    name="card"
                    className={styles.iconCard}
                />
                Основное
            </NavbarLink>
            
}

export const NavbarLink = ({ href, children, css, activePaths = [], target }) => (
    <li>
        <ActiveLink
            activePaths={activePaths}
            href={href}
            css={css}
            target={target}>
            {children}
        </ActiveLink>
    </li>
);
function ActiveLink({
    css,
    href,
    onClick,
    nofollow,
    includedPath,
    children,
    className,
    activePaths = [],
    changeLocation = true,
    allowAllPathsToBeActive,
    target
}) {
    const router = useRouter();

    const handleClick = e => {
        if (target !== "_blank") {
            e.preventDefault();

            if (onClick) onClick(e);

            if (changeLocation) router.push(href);
        }
    };

    const pathIncludesHref = (path, href) => {
        return (
            path.split("?")[0] === href ||
            path.split("#access_token")[0] === href ||
            path.split("access_token")[0] === href
        );
    };

    let active = "false";

    let path = router.asPath.split("/");
    if (path[path.length - 1] === "#") {
        path.pop();
    }
    path = path.join("/");
    path = path ? path : "/";

    if (
        pathIncludesHref(path, href) ||
        activePaths.includes(path) ||
        (allowAllPathsToBeActive && path.indexOf(href) !== -1) ||
        (includedPath && path.split("?")[0].includes(includedPath))
    ) {
        active = "true";
    }

    return (
        <a href={href} className={className} onClick={handleClick}
            active={active}
            target="_blank"
            style={css}>
            {children}
        </a>
    );
}

Solution

  • With Next.js you can check the current route and prevent navigation if you are already on that route. You can do something like if (router.asPath === href) { then don't load the route.

    Using the asPath field may lead to a mismatch between client and server if the page is rendered using server-side rendering or automatic static optimization. Avoid using asPath until the isReady field is true.

    Next.js useRouter

    function ActiveLink({ href, children, ...props }) {
      const router = useRouter();
    
      const isActive = router.asPath === href;
    
      return (
        <Link href={href}...>
          <a
            {...props}
            className={`${props.className} ${isActive ? 'active' : ''}`}
            onClick={e => {
              if (router.asPath === href) {
                e.preventDefault(); // don't reload same page
              }
            }}
          >
            {children}
          </a>
        </Link>
      );