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
相关产品推荐
相关产品推荐

