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

如何使用React Router Dom同步组件路由与状态?

浏览器激活路由与组件状态同步方案

问题场景

点击导航栏"Route 2"时,该元素会因激活路由高亮,浏览器路由显示/route2;但刷新浏览器后,导航栏会高亮Navbar组件初始状态的"Route 1",而浏览器路由仍保持/route2,需要同步二者状态。


解决方案一:使用NavLink替代自定义状态

react-router-dom提供的NavLink组件自带路由激活判断能力,无需手动维护selected状态,是最简洁的解决方案:

修改后的Navbar组件:

import { NavLink } from "react-router-dom";

const Navbar = () => {
  return (
    <div className="flex justify-between items-center sticky top-0 border-b bg-background px-4 h-12 z-10">
      <h1>App Name</h1>
      <div className="flex gap-4 h-8 items-center">
        <NavLink 
          to="/route1"
          className={({ isActive }) => cn(
            "hover:underline hover:text-blue-500",
            isActive ? "text-blue-500" : null
          )}
        >
          <h2>Route 1</h2>
        </NavLink>
        <NavLink 
          to="/route2"
          className={({ isActive }) => cn(
            "hover:underline hover:text-blue-500",
            isActive ? "text-blue-500" : null
          )}
        >
          <h2>Route 2</h2>
        </NavLink>
      </div>
    </div>
  );
};

说明:

  • NavLink会自动根据当前路由判断isActive状态
  • 通过className接收的回调函数,可根据isActive动态设置样式
  • 移除了手动维护的selected状态和点击事件,简化代码逻辑

解决方案二:通过useLocation同步路由与组件状态

如果需要保留自定义状态逻辑,可使用useLocation监听路由变化,同步更新组件状态:

修改后的Navbar组件:

import { useLocation } from "react-router-dom";

const Navbar = () => {
  const location = useLocation();
  // 根据当前路由初始化selected状态
  const [selected, setSelected] = React.useState(() => {
    return location.pathname === "/route2" ? 1 : 0;
  });

  // 监听路由变化,更新selected状态
  React.useEffect(() => {
    setSelected(location.pathname === "/route2" ? 1 : 0);
  }, [location.pathname]);

  return (
    <div className="flex justify-between items-center sticky top-0 border-b bg-background px-4 h-12 z-10">
      <h1>App Name</h1>
      <div className="flex gap-4 h-8 items-center">
        <Link to="/route1" onClick={() => setSelected(0)}>
          <h2
            className={cn(
              "hover:underline hover:text-blue-500",
              selected === 0 ? "text-blue-500" : null
            )}
          >
            Route 1
          </h2>
        </Link>
        <Link to="/route2" onClick={() => setSelected(1)}>
          <h2
            className={cn(
              "hover:underline hover:text-blue-500",
              selected === 1 ? "text-blue-500" : null
            )}
          >
            Route 2
          </h2>
        </Link>
      </div>
    </div>
  );
};

说明:

  • 使用useLocation获取当前路由信息
  • 初始化状态时根据当前路由设置selected,解决刷新后状态不一致问题
  • 通过useEffect监听location.pathname变化,实时同步状态

额外提示

原代码中Link to="route2"建议改为to="/route2",避免相对路径导致的路由跳转异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:34:54