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

React Router v6实现标签页路由及嵌套页面跨链接问题求助

React Router v6标签页嵌套路由与跨链接问题解决

问题描述

  • 访问/files时默认停留在该路径,需自动跳转至/files/raw-medias;切换标签时URL需同步更新为/files/raw-medias或/files/datasets
  • 从详情页(如/files/raw-media/1)返回时,需回到之前激活的标签页,而非默认的Raw Medias标签
  • Raw Media详情页中点击Dataset列表项,当前错误跳转到嵌套路径/files/raw-media/1/dataset/1,需改为跳转到/files/dataset/1

解决方案

1. 标签页与URL同步,实现默认跳转

修改路由配置

将/files设为父路由,嵌套标签页对应的子路由,并添加index路由实现默认跳转:

const router = createBrowserRouter([
  {
    path: "/",
    element: <HomePage />,
    children: [
      {
        path: "files",
        element: <FilesPage />,
        children: [
          // 默认重定向到raw-medias标签
          { index: true, element: <Navigate to="raw-medias" replace /> },
          { path: "raw-medias", element: <RawMediaList data={RAW_DATA} /> },
          { path: "datasets", element: <DatasetList data={DATASET_DATA} /> },
        ],
      },
      { path: "files/raw-media/:rawMediaId", element: <RawMediaPage /> },
      { path: "files/dataset/:datasetId", element: <DatasetPage /> },
    ],
  },
]);

重构FilesPage组件

移除本地状态存储标签,通过URL路径同步标签状态,使用Outlet渲染子路由内容:

import { useLocation, useNavigate, Outlet, Navigate } from "react-router-dom";
import { Stack, Button } from "@mui/material";

type Tab = "raw-medias" | "datasets";

const FilesPage = () => {
  const location = useLocation();
  const navigate = useNavigate();
  // 从URL路径提取当前激活的标签
  const currentTab = location.pathname.split("/").pop() as Tab || "raw-medias";

  const handleChangeTab = (tab: Tab) => {
    navigate(tab);
  };

  return (
    <Stack gap={2}>
      <span>FilesPage</span>
      <Stack direction="row" gap={2}>
        <Button 
          onClick={() => handleChangeTab("raw-medias")}
          variant={currentTab === "raw-medias" ? "contained" : "outlined"}
        >
          Raw Medias Tab
        </Button>
        <Button 
          onClick={() => handleChangeTab("datasets")}
          variant={currentTab === "datasets" ? "contained" : "outlined"}
        >
          Datasets Tab
        </Button>
      </Stack>
      {/* 渲染当前标签对应的子路由内容 */}
      <Outlet />
    </Stack>
  );
};

2. 返回时保持标签页激活状态

由于标签状态已与URL绑定,浏览器历史记录会保留之前的标签页路径,因此无需修改返回逻辑。只需确保列表项跳转到详情页时使用正确的路径:

// RawMediaList.tsx
import { useNavigate } from "react-router-dom";

const RawMediaList = ({ data }) => {
  const navigate = useNavigate();

  const handleClick = (id: number) => {
    // 使用绝对路径跳转到详情页
    navigate(`/files/raw-media/${id}`);
  };

  return (
    <Stack gap={1}>
      {data.map((item) => (
        <div 
          key={item.id} 
          onClick={() => handleClick(item.id)}
          style={{ padding: "8px", border: "1px solid #eee", cursor: "pointer" }}
        >
          {item.name}
        </div>
      ))}
    </Stack>
  );
};

此时点击详情页的返回按钮,会自动回到之前激活的标签页路径。

3. 修正跨标签页跳转路径

在DatasetList中使用绝对路径跳转,避免相对路径导致的嵌套错误:

// DatasetList.tsx
import { useNavigate } from "react-router-dom";
import { Stack } from "@mui/material";

const DatasetList = ({ data }) => {
  const navigate = useNavigate();

  const handleClick = (id: number) => {
    // 使用绝对路径跳转到Dataset详情页
    navigate(`/files/dataset/${id}`);
  };

  return (
    <Stack gap={1}>
      {data.map((item) => (
        <div 
          key={item.id} 
          onClick={() => handleClick(item.id)}
          style={{ padding: "8px", border: "1px solid #eee", cursor: "pointer" }}
        >
          {item.name}
        </div>
      ))}
    </Stack>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 13:05:21