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

Next.js路由跳转时Navbar组件高亮状态延迟更新问题求解

问题根因

  • 你定义的navigation数组是组件外部的全局常量,直接在useEffect中修改它的current属性不会触发React组件的重渲染,界面自然不会同步更新。你看到的「延迟更新」本质是:路由跳转时修改了全局常量的值,但要等下一次组件因为其他原因重渲染时,才会读取上一次修改后的值,所以永远慢一步。
  • useEffect依赖项配置错误:监听整个router引用对象不会精准触发回调,应该监听路由的实际变化值比如router.route。
  • 没有使用React状态管理激活项,不符合React的响应式更新逻辑。

修复方案(推荐:无需useEffect,更简洁)

直接在渲染菜单项时实时判断当前路由是否匹配,不需要额外维护current状态和副作用:

import Link from "next/link";
import { useRouter } from "next/router";

function classNames(...classes) {
  return classes.filter(Boolean).join(" ");
}

// 导航配置去掉冗余的current字段
const navigation = [
  { name: "page1", href: "/" },
  { name: "page2", href: "/page2" },
  { name: "page3", href: "/page3" },
];

export default function Navbar() {
  const router = useRouter();

  return (
    <div>
      <div>
        {navigation.map((item) => {
          // 渲染时实时判断是否为当前激活页
          const isCurrent = router.route === item.href;
          return (
            <Link href={item.href} key={item.name}>
              <a
                className={classNames(
                  isCurrent
                    ? "border-indigo-500 text-gray-900"
                    : "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700",
                  "inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
                )}
                aria-current={isCurrent ? "page" : undefined}
              >
                {item.name}
              </a>
            </Link>
          );
        })}
      </div>
    </div>
  );
}

可选方案:用状态管理激活项

如果你的业务场景需要单独维护激活状态,可以用useState配合useEffect实现:

import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";

function classNames(...classes) {
  return classes.filter(Boolean).join(" ");
}

const navigation = [
  { name: "page1", href: "/" },
  { name: "page2", href: "/page2" },
  { name: "page3", href: "/page3" },
];

export default function Navbar() {
  const router = useRouter();
  // 用状态存当前激活的路径
  const [currentPath, setCurrentPath] = useState(router.route);

  // 路由变化时更新状态,触发重渲染
  useEffect(() => {
    setCurrentPath(router.route);
  }, [router.route]); // 依赖项指定为路由字符串,精准触发

  return (
    <div>
      <div>
        {navigation.map((item) => {
          const isCurrent = currentPath === item.href;
          return (
            <Link href={item.href} key={item.name}>
              <a
                className={classNames(
                  isCurrent
                    ? "border-indigo-500 text-gray-900"
                    : "border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700",
                  "inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
                )}
                aria-current={isCurrent ? "page" : undefined}
              >
                {item.name}
              </a>
            </Link>
          );
        })}
      </div>
    </div>
  );
}

内容的提问来源于stack exchange,提问作者Brenton Beltrami

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 14:15:03