react-router-v7
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReact Router v7 Best Practices
React Router v7 最佳实践
Quick Reference
快速参考
Router Setup (Data Mode):
tsx
import { createBrowserRouter, RouterProvider } from "react-router";
const router = createBrowserRouter([
{
path: "/",
Component: Root,
ErrorBoundary: RootErrorBoundary,
loader: rootLoader,
children: [
{ index: true, Component: Home },
{ path: "products/:productId", Component: Product, loader: productLoader },
],
},
]);
ReactDOM.createRoot(root).render(<RouterProvider router={router} />);Framework Mode (Vite plugin):
ts
// routes.ts
import { index, route } from "@react-router/dev/routes";
export default [
index("./home.tsx"),
route("products/:pid", "./product.tsx"),
];路由器设置(数据模式):
tsx
import { createBrowserRouter, RouterProvider } from "react-router";
const router = createBrowserRouter([
{
path: "/",
Component: Root,
ErrorBoundary: RootErrorBoundary,
loader: rootLoader,
children: [
{ index: true, Component: Home },
{ path: "products/:productId", Component: Product, loader: productLoader },
],
},
]);
ReactDOM.createRoot(root).render(<RouterProvider router={router} />);框架模式(Vite 插件):
ts
// routes.ts
import { index, route } from "@react-router/dev/routes";
export default [
index("./home.tsx"),
route("products/:pid", "./product.tsx"),
];Route Configuration
路由配置
Nested Routes with Outlets
结合Outlet的嵌套路由
tsx
createBrowserRouter([
{
path: "/dashboard",
Component: Dashboard,
children: [
{ index: true, Component: DashboardHome },
{ path: "settings", Component: Settings },
],
},
]);
function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
<Outlet /> {/* Renders child routes */}
</div>
);
}tsx
createBrowserRouter([
{
path: "/dashboard",
Component: Dashboard,
children: [
{ index: true, Component: DashboardHome },
{ path: "settings", Component: Settings },
],
},
]);
function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
<Outlet /> {/* 渲染子路由 */}
</div>
);
}Dynamic Segments and Splats
动态分段与通配符
tsx
{ path: "teams/:teamId" } // params.teamId
{ path: ":lang?/categories" } // Optional segment
{ path: "files/*" } // Splat: params["*"]tsx
{ path: "teams/:teamId" } // params.teamId
{ path: ":lang?/categories" } // 可选分段
{ path: "files/*" } // 通配符: params["*"]Key Decision Points
关键决策点
Form vs Fetcher
Form 与 Fetcher 的选择
Use : Creating/deleting with URL change, adding to history
Use : Inline updates, list operations, popovers - no URL change
<Form>useFetcher使用 : 创建/删除操作且需要改变URL、添加到历史记录的场景
使用 : 内联更新、列表操作、弹出层等不需要改变URL的场景
<Form>useFetcherLoader vs useEffect
Loader 与 useEffect 的选择
Use loader: Data before render, server-side fetch, automatic revalidation
Use useEffect: Client-only data, user-interaction dependent, subscriptions
使用 loader: 渲染前加载数据、服务端请求、自动重新验证
使用 useEffect: 仅客户端数据、依赖用户交互、订阅类场景
Additional Documentation
额外文档
- Data Loading: See references/loaders.md for loader patterns, parallel loading, search params
- Mutations: See references/actions.md for actions, Form, fetchers, validation
- Navigation: See references/navigation.md for Link, NavLink, programmatic nav
- Advanced: See references/advanced.md for error boundaries, protected routes, lazy loading
- 数据加载: 查看 references/loaders.md 了解加载器模式、并行加载、搜索参数相关内容
- 数据变更: 查看 references/actions.md 了解动作、Form、获取器、验证相关内容
- 导航: 查看 references/navigation.md 了解Link、NavLink、编程式导航相关内容
- 进阶内容: 查看 references/advanced.md 了解错误边界、受保护路由、懒加载相关内容
Mode Comparison
模式对比
| Feature | Framework Mode | Data Mode | Declarative Mode |
|---|---|---|---|
| Setup | Vite plugin | | |
| Type Safety | Auto-generated types | Manual | Manual |
| SSR Support | Built-in | Manual | Limited |
| Use Case | Full-stack apps | SPAs with control | Simple/legacy |
| 特性 | 框架模式 | 数据模式 | 声明式模式 |
|---|---|---|---|
| 设置方式 | Vite 插件 | | |
| 类型安全 | 自动生成类型 | 手动配置 | 手动配置 |
| SSR 支持 | 内置支持 | 手动实现 | 有限支持 |
| 使用场景 | 全栈应用 | 需要控制的单页应用 | 简单/遗留项目 |