路由
在本页

路由

配置路由

通过渲染 <Routes><Route> 组件来配置路由,它们将 URL 片段与 UI 元素关联起来。

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router";
import App from "./app";

const root = document.getElementById("root");

ReactDOM.createRoot(root).render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<App />} />
    </Routes>
  </BrowserRouter>
);

这是一个更详细的配置示例

<Routes>
  <Route index element={<Home />} />
  <Route path="about" element={<About />} />

  <Route element={<AuthLayout />}>
    <Route path="login" element={<Login />} />
    <Route path="register" element={<Register />} />
  </Route>

  <Route path="concerts">
    <Route index element={<ConcertsHome />} />
    <Route path=":city" element={<City />} />
    <Route path="trending" element={<Trending />} />
  </Route>
</Routes>

嵌套路由

路由可以嵌套在父路由内部。

<Routes>
  <Route path="dashboard" element={<Dashboard />}>
    <Route index element={<Home />} />
    <Route path="settings" element={<Settings />} />
  </Route>
</Routes>

父路由的路径会自动包含在子路由中,因此此配置会创建 "/dashboard""/dashboard/settings" 这两个 URL。

子路由通过父路由中的 <Outlet/> 组件进行渲染。

import { Outlet } from "react-router";

export default function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      {/* will either be <Home/> or <Settings/> */}
      <Outlet />
    </div>
  );
}

布局路由

没有 path 的路由会为其子路由创建新的嵌套层级,但它们不会向 URL 中添加任何片段。

<Routes>
  <Route element={<MarketingLayout />}>
    <Route index element={<MarketingHome />} />
    <Route path="contact" element={<Contact />} />
  </Route>

  <Route path="projects">
    <Route index element={<ProjectsHome />} />
    <Route element={<ProjectsLayout />}>
      <Route path=":pid" element={<Project />} />
      <Route path=":pid/edit" element={<EditProject />} />
    </Route>
  </Route>
</Routes>

索引路由

索引路由在其父路由的 URL 处渲染到父路由的 <Outlet/> 中(类似于默认子路由)。它们通过 index prop 进行配置。

<Routes>
  <Route path="/" element={<Root />}>
    {/* renders into the outlet in <Root> at "/" */}
    <Route index element={<Home />} />

    <Route path="dashboard" element={<Dashboard />}>
      {/* renders into the outlet in <Dashboard> at "/dashboard" */}
      <Route index element={<DashboardHome />} />
      <Route path="settings" element={<Settings />} />
    </Route>
  </Route>
</Routes>

请注意,索引路由不能包含子路由。如果您期望这种行为,您可能需要一个布局路由

路由前缀

一个没有 element prop 的 <Route path> 会为其子路由添加一个路径前缀,而不会引入父级布局。

<Route path="projects">
  <Route index element={<ProjectsHome />} />
  <Route element={<ProjectsLayout />}>
    <Route path=":pid" element={<Project />} />
    <Route path=":pid/edit" element={<EditProject />} />
  </Route>
</Route>

动态片段

如果路径片段以 : 开头,那么它就成为一个“动态片段”。当路由匹配 URL 时,动态片段会从 URL 中解析出来,并作为 params 提供给其他路由 API,例如 useParams

<Route path="teams/:teamId" element={<Team />} />
import { useParams } from "react-router";

export default function Team() {
  let params = useParams();
  // params.teamId
}

一个路由路径中可以有多个动态片段

<Route
  path="/c/:categoryId/p/:productId"
  element={<Product />}
/>
import { useParams } from "react-router";

export default function CategoryProduct() {
  let { categoryId, productId } = useParams();
  // ...
}

您应该确保给定路径中的所有动态片段都是唯一的。否则,在填充 params 对象时,后面的动态片段值会覆盖前面的值。

可选片段

您可以通过在路径片段末尾添加 ? 来使其成为可选片段。

<Route path=":lang?/categories" element={<Categories />} />

您也可以拥有可选的静态片段

<Route path="users/:userId/edit?" element={<User />} />

通配符路由

也称为“通配符”(catchall)和“星号段”(star segments)。如果路由路径模式以 /* 结尾,那么它将匹配 / 后面的任何字符,包括其他 / 字符。

<Route path="files/*" element={<File />} />
let params = useParams();
// params["*"] will contain the remaining URL after files/
let filePath = params["*"];

你可以解构 *,只需要给它指定一个新名称。一个常用的名称是 splat

let { "*": splat } = useParams();

链接

使用 LinkNavLink 从你的 UI 链接到路由

import { NavLink, Link } from "react-router";

function Header() {
  return (
    <nav>
      {/* NavLink makes it easy to show active states */}
      <NavLink
        to="/"
        className={({ isActive }) =>
          isActive ? "active" : ""
        }
      >
        Home
      </NavLink>

      <Link to="/concerts/salt-lake-city">Concerts</Link>
    </nav>
  );
}

下一篇: 导航

文档和示例 CC 4.0