React Router 的路由方式
在 7.x 里主要有两种路由写法:
1. 配置式路由 (Config-based Routing)
直接用createBrowserRouter() 或 <Routes>/<Route> 写路由表。
适合小项目、灵活控制。
例子:
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";
const router = createBrowserRouter([
{ path: "/", element: <Home /> },
{ path: "/about", element: <About /> },
]);
export default function App() {
return <RouterProvider router={router} />;
}
2. 基于文件的路由 (File-based Routing) ✅
- 新增于 React Router v7 (实验特性),类似 Remix、Next.js;
- 通过文件系统来约定路由,不需要自己手写配置;
- 适合中大型项目,目录结构清晰,约定优于配置;
基于文件的路由(File-based Routing)
1. 基本概念
- 文件路径建议匹配路由路径
routes/home.tsx → /homeroutes/course01/index.tsx → /course01routes/course01/lesson.tsx → /course01/lesson
- 动态路由
[id].tsx→/course01/123[slug].tsx → /course01/react-router
- 嵌套路由
- 文件夹就是父路由,子文件就是子路由;
- 比如:
routes/
├── course01/
│ ├── index.tsx → /course01
│ ├── hello-world.tsx → /course01/hello-world
│ └── [id].tsx → /course01/:id
2. routes.js的作用
虽然文件决定了路由,但 React Router 仍然需要一个配置文件(通常是routes.ts)来把目录映射到框架。
例子:
import { type RouteConfig, index, route } from "@react-router/dev/routes";
export default [
index("routes/home.tsx"),
route("test01", "routes/test01/test01.tsx"),
route("course01", "routes/course01/index.tsx"),
route(
"course01/02-hello-react/01-hello-react",
"routes/course01/c02-hello-react/01-hello-react.tsx"
),
route(
"course01/02-hello-react/02-3api-detail",
"routes/course01/c02-hello-react/02-3api-detail.tsx"
),
] satisfies RouteConfig;
3. 动态路由(Dynamic Routes)
文件名用 [] 包裹参数:
routes/posts/[id].tsx→/posts/:id- 在组件里用
useParams()获取参数:
import { useParams } from "react-router-dom";
export default function Post() {
const { id } = useParams();
return <h1>Post ID: {id}</h1>;
}
4. 嵌套路由(Nested Routes)
父文件夹 → 父路由;子文件 → 子路由。例如:
routes/
├── dashboard/
│ ├── index.tsx → /dashboard
│ ├── settings.tsx → /dashboard/settings
│ └── [id].tsx → /dashboard/:id
示例:
import { type RouteConfig, route } from "@react-router/dev/routes";
export default [
route("course01", "routes/course01/index.tsx", [
route("hello-world", "routes/course01/hello-world.tsx"),
route(":id", "routes/course01/[id].tsx"),
]),
] satisfies RouteConfig;
5. 加载数据和提交 (Loader & Action)
文件路由和 Remix 很像,每个 .tsx 文件还可以导出数据函数:
// routes/posts/[id].tsx
import { json, useLoaderData } from "react-router-dom";
export async function loader({ params }) {
return json({ postId: params.id });
}
export default function Post() {
const data = useLoaderData();
return <h1>Post ID: {data.postId}</h1>;
}
- loader → 在进入页面前加载数据
- action → 处理表单提交