javascript 如何使标签路由与React路由器v6与交叉链接在嵌套页面?

u91tlkcl  于 2022-12-02  发布在  Java
关注(0)|答案(1)|浏览(131)

I'm trying to make a nested routing with tabs on a page and cross-linking but no success. Please help to make it work.

  1. I have a route /files which contains two tabs: Raw Medias tab and Datasets tab . On tab switching page url is not changed it's always the same /files . How can I make page url changes on tab switching? For example, default tab on page /files is Raw Medias. So how to make it: if user lands on /files page then page url is /files/raw-medias . If user switches on Dataset tab then page url should be /files/datasets .
  2. Each tab has a list with clickable items. On item click item's page opens /files/raw-medias/id . This page has Back button. On click Back button opens /files page with active default tab. How to make so that on Back button click opens /files page with active tab for that item? For example if active tab is Dataset tab and user clicks on item and then on Back button then Dataset tab should be active.
  3. Raw Media Page has a list. This list is the content of Dataset tab (cross linking). How to make so if user clicks on item in that list then he should land Dataset item page? For example, user is on /files/raw-media/id and click on an item in list then /files/dataset/id page should open. At the moment I get an error because on this this url opens /files/raw-media/id/dataset/id

Codesandboxhttps://codesandbox.io/s/react-router-tabs-ciivld?file=/src/App.tsx

My routes:

const router = createBrowserRouter([
  {
    path: "/",
    element: <HomePage />,
    children: [
      {
        path: "/files",
        element: <FilesPage />
      },
      {
        path: "files/raw-media/:rawMediaId",
        element: <RawMediaPage />
      },
      {
        path: "files/dataset/:datasetId",
        element: <DatasetPage />
      }
    ]
  }
]);

Tabs page

type Tab = "raw-medias" | "datasets";
    
    const FilesPage = () => {
      const [tab, setTab] = useState<Tab>("raw-medias");
    
      const handleChangeTab = (tab: Tab) => {
        setTab(tab);
      };
    
      return (
        <Stack>
            FilesPage
            <Button onClick={() => handleChangeTab("raw-medias")}>
              Raw Medias Tab
            </Button>
            <Button onClick={() => handleChangeTab("datasets")}>
              Datasets Tab
            </Button>
    
            {tab === "raw-medias" ? <RawMediaList data={RAW_DATA} /> : null}
            {tab === "datasets" ? <DatasetList data={DATASET_DATA} /> : null}
        </Stack>
      );
    };

RawMediaPage.tsx (single item page with Back button)

const RawMediaPage = () => {
  const { rawMediaId } = useParams();
  const navigate = useNavigate();

  return (
    <Stack>
      <Typography>
        This is RAW Media Page
      </Typography>
      <Button onClick={() => navigate(-1)}>
        Go Back to tab list
      </Button>

      <Stack>
        This is Dataset List on RAW Media Page
        <DatasetList data={DATASET_DATA} />
      </Stack>
    </Stack>
  );
};

DatasetList.tsx (list with clickable items)

const navigate = useNavigate();

  const handleClick = (id: number) => {
    navigate(`dataset/${id}`);
  };

  return (
    <Stack>
      {data.map((item) => {
        return (
          <Box onClick={() => handleClick(item.id)} key={item.id}>
            {item.name}
          </Box>
        );
      })}
    </Stack>
  );
};
2skhul33

2skhul331#

文件页.tsx

配置FilesPage组件,将当前匹配的路由与一个“tab”耦合。我们在这里使用NavLink组件在tab***和***之间导航,通过使用NavLinkisActive子属性免费获得“tab matching”。

import { Stack, Typography, Button } from "@mui/material";
import { NavLink, Outlet } from "react-router-dom";

const FilesPage = () => {
  return (
    <Stack gap={"30px"}>
      <Typography variant="h4" align={"center"}>
        FilesPage
      </Typography>
      <Stack direction={"row"} gap={"10px"}>
        <NavLink className="tab-link" to="raw-medias">
          {({ isActive }: { isActive: boolean }) => (
            <Button
              variant="contained"
              sx={{ background: isActive ? undefined : "gray" }}
            >
              Raw Medias Tab
            </Button>
          )}
        </NavLink>
        <NavLink className="tab-link" to="datasets">
          {({ isActive }: { isActive: boolean }) => (
            <Button
              variant="contained"
              sx={{ background: isActive ? undefined : "gray" }}
            >
              Datasets Tab
            </Button>
          )}
        </NavLink>
      </Stack>

      <Stack>
        <Outlet />
      </Stack>
    </Stack>
  );
};

export default FilesPage;

CSS

.tab-link {
  text-decoration: none;
}

应用程序tsx

配置路线,使嵌套路线由FilePages呈现为布局路线。

import "./styles.css";
import {
  createBrowserRouter,
  RouterProvider,
  Navigate
} from "react-router-dom";
import { Box } from "@mui/material";
import HomePage from "./HomePage";
import FilesPage from "./FilesPage";
import RawMediaList from "./RawMediaList";
import DatasetList from "./DatasetList";
import RawMediaPage from "./RawMediaPage";
import DatasetPage from "./DatasetPage";
import { RAW_DATA, DATASET_DATA } from "./mockData";

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

export default function App() {
  return (
    <Box>
      <RouterProvider router={router} />
    </Box>
  );
}

原始媒体列表和数据集列表

这些组件需要呈现指向特定详细页的链接。
第一个
请注意,DatasetList使用绝对路径,因为它由两个选项卡呈现,所以它不能从一个选项卡相对链接到另一个选项卡。

演示

相关问题