一、设计思想与核心原理
1. 设计哲学
- 组件即路由 :路由以
<Route>
组件形式声明,与 React 组件树深度集成 - 声明式导航 :通过
<Link>
和useNavigate
实现无刷新路由跳转 - 动态匹配机制:路径参数、通配符、优先级匹配规则
- 数据路由 (v6.4+):支持
loader
/action
实现路由级数据预加载
2. 核心架构
jsx
// 数据路由配置示例(v7推荐方式)
const router = createBrowserRouter([
{
path: "/",
element: <Root />,
loader: rootLoader, // 数据预加载
children: [
{
index: true,
element: <Home />
},
{
path: "user/:id",
element: <User />,
loader: userLoader
}
]
}
]);
核心模块:
history
包:统一管理浏览器历史栈(BrowserHistory/HashHistory)- 路由匹配引擎:基于路径模式的正则匹配算法
- 上下文传递:通过
RouterProvider
全局注入路由上下文
二、安装与基础配置
1. 安装
bash
npm install [email protected]
2. 基础配置
方式1:传统组件式配置
jsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="users" element={<Users />}>
<Route path=":id" element={<UserDetail />} />
</Route>
</Routes>
</BrowserRouter>
);
}
方式2:数据路由配置(推荐)
jsx
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
const router = createBrowserRouter([
{
path: "/",
element: <Layout />,
children: [
{ index: true, element: <Dashboard /> },
{ path: "projects", element: <Projects /> }
]
}
]);
function Root() {
return <RouterProvider router={router} />;
}
三、核心API全解析
1. 核心组件
组件 | 作用 |
---|---|
<BrowserRouter> |
使用HTML5 History API的路由容器 |
<Routes> |
路由匹配容器(v6+替代Switch) |
<Route> |
定义路由规则,支持嵌套结构 |
<Link> |
声明式导航组件,支持相对路径 |
<Outlet> |
子路由渲染占位符 |
2. 关键Hooks
Hook | 作用 |
---|---|
useNavigate |
获取编程式导航函数(替代v5的useHistory) |
useParams |
获取动态路由参数 |
useLoaderData |
获取loader加载的数据(数据路由专用) |
useRoutes |
通过配置对象定义路由(替代react-router-config) |
四、多级路由配置实践
1. 三级路由结构示例
jsx
// 使用createBrowserRouter配置
const router = createBrowserRouter([
{
path: "/",
element: <MainLayout />,
children: [
{ index: true, element: <Home /> }, // 一级路由
{
path: "products",
element: <ProductLayout />, // 二级布局
children: [
{ index: true, element: <ProductList /> },
{
path: ":productId",
element: <ProductDetail />, // 三级布局
children: [
{ path: "spec", element: <ProductSpec /> } // 四级路由
]
}
]
}
]
}
]);
2. 动态参数透传
jsx
// 三级路由获取参数
function ProductSpec() {
// 自动获取所有层级的参数
const params = useParams();
console.log(params.productId); // 来自二级路由
return <div>规格详情</div>;
}
3. 相对路径最佳实践
jsx
// 在二级路由中使用相对路径
<Link to="../new">返回上级</Link> // 等效于 "/products/new"
五、优化方案与高级技巧
1. 性能优化
jsx
// 动态导入 + Suspense
const ProductList = React.lazy(() => import('./ProductList'));
{
path: "products",
element: (
<Suspense fallback={<Loading />}>
<ProductLayout />
</Suspense>
)
}
2. 路由预加载策略
jsx
// 使用prefetchLink
<link
rel="prefetch"
href="/_next/static/chunks/ProductDetail.js"
as="script"
/>
// 或编程式预加载
const navigate = useNavigate();
const handleHover = () => import('./ProductDetail');
3. 路由守卫实现
jsx
// 高阶组件保护路由
const PrivateRoute = ({ children }) => {
const { isAuth } = useAuth();
return isAuth ? children : <Navigate to="/login" />;
};
// 路由配置中应用
{
path: "dashboard",
element: <PrivateRoute><Dashboard /></PrivateRoute>
}
六、注意事项与最佳实践
1. 版本升级重点
-
移除exact属性:v6+默认精确匹配
-
路径匹配规则变更 :
jsx// v5:/user 会匹配 /user/* // v6+:需要显式添加通配符 <Route path="user/*" ... />
-
类组件兼容:推荐使用函数组件+Hooks
2. 常见问题排查
jsx
// 错误:未使用Routes包裹
<BrowserRouter>
<Route path="/" ... /> ❌
<Routes> ✅
<Route ... />
</Routes>
</BrowserRouter>
// 错误:错误使用component属性
<Route path="/old" component={OldComponent} /> ❌
<Route path="/new" element={<NewComponent />} /> ✅
3. 服务端渲染配置
jsx
// 服务端使用StaticRouter
app.get('*', (req, res) => {
const router = createStaticRouter(
router.routes,
{ location: req.url }
);
// 渲染逻辑...
});
// 客户端水合
hydrateRoot(
document,
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
七、总结与最佳实践
- 路由分层管理:按功能模块组织路由结构
- 数据驱动优先:充分利用loader/action处理数据流
- 组件拆分原则:路由组件与业务组件分离
- 错误边界处理:使用errorElement处理路由级异常
- 渐进式迁移:从传统模式逐步过渡到数据路由
jsx
// 完整的最佳实践示例
const router = createBrowserRouter(
createRoutesFromElements(
<Route
path="/"
element={<RootLayout />}
errorElement={<GlobalError />}
>
<Route errorElement={<AuthError />}>
<Route element={<AuthGuard />}>
<Route path="dashboard" element={<Dashboard />} />
</Route>
</Route>
<Route path="login" element={<Login />} loader={loginLoader} />
</Route>
)
);
官方文档参考:React Router v7 Documentation
八、高级路由模式实现
1. 动态路由注册
jsx
// 根据用户权限动态生成路由
const dynamicRoutes = (permissions) => [
{
path: "/",
element: <BaseLayout />,
children: [
permissions.includes('admin') && {
path: "admin",
element: <AdminPanel />
},
{ path: "*", element: <NotFound /> }
].filter(Boolean)
}
];
function App() {
const { user } = useAuth();
return <RouterProvider router={createBrowserRouter(dynamicRoutes(user?.permissions))} />;
}
2. 模态路由(Modal Routing)
jsx
// 通过URL参数控制模态显示
<Route
path="users"
element={<UserList />}
>
<Route
path=":userId/edit"
element={<Modal><UserEdit /></Modal>}
// 保持主界面可见
loader={({ request }) => {
const url = new URL(request.url);
url.searchParams.set("modal", "true");
return redirect(url.toString());
}}
/>
</Route>
九、数据流管理最佳实践
1. 数据路由完整工作流
jsx
// 路由配置
{
path: "posts/:postId",
element: <PostDetail />,
loader: async ({ params }) => {
return fetchPost(params.postId);
},
action: async ({ request }) => {
const formData = await request.formData();
return updatePost(formData);
}
}
// 组件内使用
function PostDetail() {
const post = useLoaderData(); // 获取loader数据
const { Form } = useFormAction(); // 获取action处理器
return (
<Form method="post">
<input name="content" defaultValue={post.content} />
<button type="submit">保存</button>
</Form>
);
}
2. 全局状态与路由集成
jsx
// 创建增强版RouterProvider
const StatefulRouter = () => {
const [globalState, dispatch] = useReducer(reducer, initialState);
return (
<StateContext.Provider value={{ globalState, dispatch }}>
<RouterProvider router={router} />
</StateContext.Provider>
);
};
// 在loader中访问全局状态
const authLoader = ({ context }) => {
if (!context.globalState.isLoggedIn) {
throw redirect("/login");
}
return null;
};
十、微前端架构下的路由方案
1. 主应用路由配置
jsx
const mainRouter = createBrowserRouter([
{
path: "/*",
element: <MainApp />,
children: [
{ path: "dashboard/*", element: <DashboardMF /> },
{ path: "admin/*", element: <AdminMF /> }
]
}
]);
// 主应用布局组件
function MainApp() {
return (
<div>
<Header />
<Outlet /> {/* 微前端子应用渲染区 */}
</div>
);
}
2. 子应用路由隔离
jsx
// 子应用独立路由配置
const subRouter = createBrowserRouter(
createRoutesFromElements(
<Route path="/dashboard/*" element={<SubAppLayout />}>
<Route path="analytics" element={<Analytics />} />
<Route path="reports" element={<Reports />} />
</Route>
),
{
basename: "/dashboard" // 设置基础路径
}
);
// 子应用入口适配
export function SubApp() {
return (
<RouterProvider router={subRouter}
future={{ v7_startTransition: true }} />
);
}
十一、性能监控与优化指标
1. 路由性能追踪
jsx
// 路由性能监控中间件
const perfRouter = createBrowserRouter(
routes.map(route => ({
...route,
loader: async (args) => {
const start = performance.now();
const result = await route.loader?.(args);
const duration = performance.now() - start;
reportPerfMetric(route.path, duration);
return result;
}
}))
);
2. 关键性能指标(KPIs)
指标 | 优化目标 | 测量方法 |
---|---|---|
首次路由渲染时间 | <200ms | Navigation Timing API |
路由切换延迟 | <100ms | Route change event listeners |
预加载命中率 | >85% | Link prefetch tracking |
错误路由发生率 | <0.1% | Error boundary 捕获 |
十二、TypeScript 深度集成
1. 类型安全路由配置
typescript
// 定义类型化路由参数
declare module 'react-router-dom' {
interface ParamKeys {
userId: string;
projectId: number;
}
}
// 使用类型化hooks
const { userId } = useParams<{ userId: string }>();
const navigate = useNavigate<RoutePaths>(); // 预定义路径枚举
2. 类型化数据路由
typescript
interface PostData {
id: number;
title: string;
content: string;
}
const router = createBrowserRouter([
{
path: "/posts/:postId",
element: <PostDetail />,
loader: async ({ params }): Promise<PostData> => {
return fetchPost(params.postId);
}
}
]);
function PostDetail() {
const post = useLoaderData() as PostData; // 安全类型断言
}
十三、移动端特殊处理
1. 手势导航支持
jsx
// 滑动返回监听
function MobileRouter() {
const navigate = useNavigate();
const [touchStart, setTouchStart] = useState(0);
return (
<div
onTouchStart={(e) => setTouchStart(e.touches[0].clientX)}
onTouchEnd={(e) => {
if (touchStart - e.changedTouches[0].clientX > 50) {
navigate(1); // 前进
} else if (e.changedTouches[0].clientX - touchStart > 50) {
navigate(-1); // 后退
}
}}
>
<Outlet />
</div>
);
}
2. 移动端性能优化
jsx
// 视图过渡API集成
const navigate = useNavigate();
const handleNavigate = (to) => {
if (!document.startViewTransition) {
return navigate(to);
}
document.startViewTransition(() => {
navigate(to, { state: { isTransitioning: true } });
});
};
十四、生态工具链整合
1. 与状态管理库集成
jsx
// Redux中间件监听路由变化
const routerMiddleware = (store) => (next) => (action) => {
if (action.type === '@@router/NAVIGATE') {
store.dispatch({ type: 'ROUTE_CHANGED', payload: action.payload });
}
return next(action);
};
// 在路由loader中访问Store
const authLoader = ({ context }) => {
const state = context.store.getState();
return state.auth.isLoggedIn ? null : redirect('/login');
};
2. 与GraphQL集成
jsx
// 路由级数据预取
const postRoute = {
path: "posts/:id",
element: <PostDetail />,
loader: async ({ params }) => ({
post: await client.query(POST_QUERY, { id: params.id }),
comments: await client.query(COMMENTS_QUERY, { postId: params.id })
}),
shouldRevalidate: ({ currentParams, nextParams }) =>
currentParams.id !== nextParams.id
};
十五、未来演进方向
1. React Server Components 集成
jsx
// 服务端路由组件
async function ProductPage({ params }) {
const product = await fetchProduct(params.id);
return (
<ProductLayout>
<ProductDetails product={product} />
<Suspense fallback={<ReviewsLoading />}>
{/* 客户端组件 */}
<ClientReviews productId={params.id} />
</Suspense>
</ProductLayout>
);
}
// 路由配置
const router = createBrowserRouter([
{
path: "/products/:id",
element: <ProductPage />,
// 启用服务端渲染
hydrateFallback: true
}
]);
2. 智能化预加载
jsx
// 基于用户行为的预测加载
const SmartLink = ({ to, children }) => {
const prefetch = usePrefetchBehavior(); // AI预测模型
return (
<Link
to={to}
onMouseEnter={() => prefetch(to)}
onFocus={() => prefetch(to)}
>
{children}
</Link>
);
};