You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js自定义RoutingLink组件激活状态未更新问题

问题分析

你的自定义RoutingLink组件在切换链接时,旧链接的激活样式无法清除,核心原因有三个:

  1. 未处理路径不匹配场景:useEffect仅在pathname.slice(1)等于href时设置激活状态为true,但路径切换后不匹配时,没有将状态重置为false。
  2. 清理函数无效:你在useEffect内部定义了清理函数但未return,导致它不会被执行,无法在路径变化时重置状态。
  3. 初始状态错误:默认isLinkActive为false,首次渲染时如果当前路径匹配该链接,状态无法及时更新。

修复方案

最简洁可靠的方式是直接在渲染时计算激活状态,彻底避免状态不同步问题:

"use client";

import { useLocale } from "next-intl";
import Link from "next/link";
import { usePathname } from "next/navigation";
import React 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 = pathname.slice(1) === href;

    // 拼接最终类名
    const finalClassName = `${className} ${isLinkActive ? (activeClass || "text-primaryHover") : ""}`;

    return (
        <Link href={`/${currentLocale}/${href}`} className={finalClassName}>
            {children}
        </Link>
    );
}

方案优势

  1. 彻底解决状态不同步:每次渲染时直接读取当前pathname判断激活状态,不需要依赖useEffect更新状态,从根源上避免旧链接残留激活样式的问题。
  2. 代码更简洁:去掉了不必要的useState和useEffect,减少了状态管理的复杂度。
  3. 初始状态准确:首次渲染时就能立即判断链接是否激活,不会出现延迟更新的情况。

保留useState的替代修复

如果一定要保留状态管理的写法,需修正useEffect的逻辑并补充依赖:

"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>(pathname.slice(1) === href);

    useEffect(() => {
        // 路径变化时更新激活状态,不管匹配与否
        setIsLinkActive(pathname.slice(1) === href);
    }, [pathname, href]); // 必须将href加入依赖数组,避免闭包问题

    const activeClassName = isLinkActive ? (activeClass || "text-primaryHover") : "";

    return (
        <Link href={`/${currentLocale}/${href}`} className={`${className} ${activeClassName}`}>
            {children}
        </Link>
    );
}

内容的提问来源于stack exchange,提问作者Abdelrhman Gad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 22:37:45