路由透過渲染 <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
屬性設定
<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
屬性的 <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 Team() {
let { categoryId, productId } = useParams();
// ...
}
您應確保給定路徑中的所有動態區段都是唯一的。否則,當 params
物件被填充時,後面的動態區段值將覆蓋較早的值。
您可以透過在區段末尾新增 ?
來使路由區段成為選用的。
<Route path=":lang?/categories" element={<Categories />} />
您也可以有選用的靜態區段
<Route path="users/:userId/edit?" component={<User />} />
也稱為「catchall」和「star」區段。如果路由路徑模式以 /*
結尾,則它將匹配 /
後面的任何字元,包括其他 /
字元。
<Route path="files/*" element={<File />} />
let params = useParams();
// params["*"] will contain the remaining URL after files/
let filePath = params["*"];
您可以解構 *
,您只需要為其分配一個新名稱。一個常見的名稱是 splat
let { "*": splat } = useParams();
使用 Link
和 NavLink
從您的 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>
);
}