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

React Router v6嵌套路由标签页激活状态异常及修复

问题:React Router v6标签页路由返回后激活状态异常

问题场景

  • 父路由/files包含/raw-medias和/datasets两个子路由,默认重定向到/files/raw-medias,通过标签页切换子路由
  • 操作流程:点击Datasets标签页 → 点击列表条目进入详情页 → 点击返回按钮,路由回到/files/datasets,但激活的却是Raw Media标签页
  • 详情页路由files/raw-medias/:rawMediaId和files/datasets/:datasetId放在/files路由外部,因为需要使用HomePage的<Outlet />

现有代码

路由配置

const router = createBrowserRouter([
  {
    path: "/",
    element: <HomePage />,
    children: [
      {
        path: "/files",
        element: <FilesPage />,
        children: [
          {
            path: "raw-medias",
            element: <RawMediaList data={RAW_DATA} />
          },
          {
            path: "datasets",
            element: <DatasetList data={DATASET_DATA} />
          },
          {
            index: true,
            element: <Navigate to="./raw-medias" replace />
          }
        ]
      },
      {
        path: "files/raw-medias/:rawMediaId",
        element: <RawMediaPage />
      },
      {
        path: "files/datasets/:datasetId",
        element: <DatasetPage />
      }
    ]
  }
]);

FilesPage组件

const FilesPage = () => {
  const [tab, setTab] = useState<Tabs>("rawMedia");

  const handleTabs = (
    event: React.MouseEvent<HTMLElement>,
    tab: Tabs | null
  ) => {
    if (tab !== null) {
      setTab(tab);
    }
  };
  return (
    <Stack>
        <ToggleButtonGroup value={tab} onChange={handleTabs} exclusive>
          <ToggleButton
            value="rawMedia"
            component={NavLink}
            to="raw-medias"
          >
            RAW Media
          </ToggleButton>
          <ToggleButton value="dataset" component={NavLink} to="datasets">
            Datasets
          </ToggleButton>
        </ToggleButtonGroup>
      <Stack>
        <Outlet />
      </Stack>
    </Stack>
  );
};

尝试的修复及新问题

尝试通过路由路径动态设置初始tab值:

const userLocation = location?.pathname?.split('/').at(-1) as Tabs;
const [tab, setTab] = useState<Tabs>(userLocation);
  • 解决了返回时标签激活错误的问题
  • 新bug:从/路由返回/files时,没有标签页被高亮,推测是/files到./raw-medias的重定向导致

解决方案

核心问题是tab状态未与路由实时同步,且初始状态未处理重定向后的路由情况。修改后的FilesPage代码如下:

import { useLocation, Outlet, NavLink } from 'react-router-dom';
import { Stack, ToggleButton, ToggleButtonGroup } from '@mui/material';
import { useEffect, useState } from 'react';

type Tabs = 'rawMedia' | 'dataset';

const FilesPage = () => {
  const location = useLocation();
  const [tab, setTab] = useState<Tabs>('rawMedia');

  // 监听路由变化,同步tab状态
  useEffect(() => {
    const pathSegments = location.pathname.split('/');
    const lastSegment = pathSegments.at(-1);
    
    // 根据路由匹配对应tab
    if (lastSegment === 'datasets') {
      setTab('dataset');
    } else if (lastSegment === 'raw-medias' || pathSegments.includes('raw-medias')) {
      setTab('rawMedia');
    }
  }, [location]);

  const handleTabs = (
    event: React.MouseEvent<HTMLElement>,
    newTab: Tabs | null
  ) => {
    if (newTab !== null) {
      setTab(newTab);
    }
  };

  return (
    <Stack>
      <ToggleButtonGroup value={tab} onChange={handleTabs} exclusive>
        <ToggleButton
          value="rawMedia"
          component={NavLink}
          to="raw-medias"
        >
          RAW Media
        </ToggleButton>
        <ToggleButton value="dataset" component={NavLink} to="datasets">
          Datasets
        </ToggleButton>
      </ToggleButtonGroup>
      <Stack>
        <Outlet />
      </Stack>
    </Stack>
  );
};

export default FilesPage;

关键改进点

  1. 路由状态同步:通过useEffect监听location变化,每次路由更新时自动匹配并更新tab状态,彻底解决返回时标签激活错误的问题
  2. 覆盖重定向场景:完善路由匹配逻辑,当路径包含raw-medias(包括/files重定向后的/files/raw-medias)时,自动激活RAW Media标签,解决从/返回/files时无标签高亮的问题
  3. 保留交互逻辑:保留原有的标签点击切换逻辑,不影响用户正常操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:55:43