React Router 完全指南:从基础到高级实践
目录
-
路由基础概念
- 现代前端路由原理
- React Router 核心组成
- v6 版本重大改进
-
基础路由配置
- 项目初始化与安装
- 路由树形结构设计
- 基本导航实现
-
动态路由进阶
- URL 参数处理
- 搜索参数管理
- 编程式导航控制
-
嵌套路由体系
- 布局路由设计模式
- 多级路由配置实战
- Outlet 组件深度解析
-
高级路由功能
- 路由懒加载优化
- 路由守卫与权限控制
- 滚动行为管理
-
服务端集成方案
- SSR 适配指南
- 静态站点生成策略
- 数据预加载模式
-
性能优化实践
- 路由代码分割
- 预加载策略
- 缓存路由状态
-
常见问题解析
- 404 页面处理
- 重定向方案对比
- 路由冲突解决
一、路由基础概念
1.1 前端路由演进史
// 传统多页应用
// 每次跳转都需要整页刷新
// 现代 SPA 路由
history.pushState({}, '', '/new-url');
window.dispatchEvent(new PopStateEvent('popstate'));
1.2 React Router 核心组件
组件 | 作用 | v6 变化 |
---|---|---|
BrowserRouter | HTML5 History 路由容器 | 改用 createBrowserRouter |
Routes | 路由规则容器 | 替代旧版 Switch |
Route | 单一路由定义 | element 属性替代 component |
Link | 声明式导航 | 新增 relative 属性 |
Navigate | 重定向组件 | 替代 Redirect |
Outlet | 嵌套路由占位符 | 替代旧版 children |
1.3 v6 版本核心改进
- 更简洁的嵌套路由语法
- 相对路径和链接
- 改进的路由匹配算法
- 更强大的 Loader/Action API
- 内置路由错误处理
二、基础路由配置
2.1 项目初始化
npm install react-router-dom@6
2.2 路由树配置
// main.jsx
import {
createBrowserRouter,
RouterProvider
} from 'react-router-dom';
const router = createBrowserRouter([
{
path: "/",
element: <Layout />,
children: [
{ index: true, element: <Home /> },
{ path: "products", element: <ProductList /> },
{ path: "about", element: <About /> }
]
}
]);
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
2.3 导航实现
// Layout.jsx
import { Link, Outlet } from 'react-router-dom';
export default function Layout() {
return (
<div>
<nav>
<Link to="/">首页</Link>
<Link to="products">商品</Link>
<Link to="about">关于</Link>
</nav>
<main>
<Outlet />
</main>
</div>
);
}
三、动态路由进阶
3.1 URL 参数处理
// 路由配置
{
path: "products/:id",
element: <ProductDetail />,
loader: ({ params }) => fetchProduct(params.id)
}
// 组件内获取参数
import { useParams } from 'react-router-dom';
function ProductDetail() {
const { id } = useParams();
// ...
}
3.2 搜索参数管理
// 获取搜索参数
import { useSearchParams } from 'react-router-dom';
function SearchPage() {
const [searchParams, setSearchParams] = useSearchParams();
const keyword = searchParams.get("q");
const handleSearch = (text) => {
setSearchParams({ q: text });
};
}
3.3 编程式导航
import { useNavigate } from 'react-router-dom';
function LoginForm() {
const navigate = useNavigate();
const handleSubmit = async () => {
await login();
navigate("/dashboard", { replace: true });
};
}
四、嵌套路由体系
4.1 布局路由设计
// 路由配置
{
path: "/dashboard",
element: <DashboardLayout />,
children: [
{ index: true, element: <DashboardHome /> },
{ path: "settings", element: <Settings /> },
{ path: "analytics", element: <Analytics /> }
]
}
// DashboardLayout.jsx
export function DashboardLayout() {
return (
<div className="dashboard">
<Sidebar />
<div className="content">
<Outlet />
</div>
</div>
);
}
4.2 多级嵌套路由
{
path: "users",
element: <UserManagement />,
children: [
{ index: true, element: <UserList /> },
{
path: ":userId",
element: <UserDetail />,
children: [
{ path: "profile", element: <Profile /> },
{ path: "security", element: <Security /> }
]
}
]
}
五、高级路由功能
5.1 路由懒加载优化
// 动态导入组件
const ProductList = lazy(() => import('./pages/ProductList'));
// 配置路由时使用 Suspense
{
path: "products",
element: (
<Suspense fallback={<Loading />}>
<ProductList />
</Suspense>
)
}
5.2 路由守卫实现
// 高阶组件形式
const ProtectedRoute = ({ children }) => {
const { user } = useAuth();
const location = useLocation();
if (!user) {
return <Navigate to="/login" state={{ from: location }} replace />;
}
return children;
};
// 路由配置使用
{
path: "dashboard",
element: <ProtectedRoute><Dashboard /></ProtectedRoute>
}
5.3 滚动恢复方案
// 自定义滚动行为
<Router
scrollRestoration="manual"
onRestoreScroll={(position, { action }) => {
if (action === 'POP') {
window.scrollTo(position);
}
}}
>
{/* 应用内容 */}
</Router>
六、服务端集成方案
6.1 SSR 适配
// Express 服务端
app.get('*', (req, res) => {
const router = createStaticRouter(routes, {
location: req.url,
basename: process.env.BASE_URL
});
const html = ReactDOMServer.renderToString(
<StaticRouterProvider router={router} />
);
res.send(`
<html>
<body>
<div id="root">${html}</div>
<script src="/client.js"></script>
</body>
</html>
`);
});
6.2 数据预加载
// 路由配置
{
path: "blog/:slug",
element: <BlogPost />,
loader: async ({ params }) => {
return fetchPost(params.slug);
}
}
// 组件内获取数据
import { useLoaderData } from 'react-router-dom';
function BlogPost() {
const post = useLoaderData();
// ...
}
七、性能优化实践
7.1 代码分割策略
// 使用 React.lazy 和 import()
const ProductDetail = lazy(
() => import('./pages/ProductDetail')
);
// 配置路由时添加 Suspense
{
path: "products/:id",
element: (
<Suspense fallback={<Spinner />}>
<ProductDetail />
</Suspense>
)
}
7.2 预加载机制
// 鼠标悬停预加载
<Link
to="/products/123"
onMouseEnter={() => import('./pages/ProductDetail')}
>
商品详情
</Link>
八、常见问题解析
8.1 404 页面处理
// 路由配置最后添加
{
path: "*",
element: <NotFoundPage />
}
8.2 重定向方案对比
// 组件内重定向
<Route path="/old" element={<Navigate to="/new" replace />} />
// 动作重定向
const action = async () => {
await deletePost();
return redirect("/posts");
};
总结与最佳实践
9.1 版本选择建议
项目类型 | 推荐版本 | 核心优势 |
---|---|---|
新项目 | v6 | 现代 API,更好维护 |
大型现有项目 | v5 | 平滑过渡,风险可控 |
需要兼容 IE11 | v5 | 更好的浏览器支持 |
9.2 性能优化检查表
- 启用路由懒加载
- 实现代码分割
- 添加路由预加载
- 配置正确缓存策略
- 优化数据加载流程
- 使用 Suspense 边界
9.3 学习资源推荐
- 官方文档:reactrouter.com
- GitHub 仓库:React Training/react-router
- 实战案例库:React Router Cookbook
- 调试工具:React Router DevTools
通过本文的系统学习,您已经掌握了 React Router 从基础配置到企业级应用的全套技能。建议在实际项目中逐步应用这些技术,先从核心路由结构开始,逐步添加高级功能,最终构建出高性能、易维护的现代化前端路由体系。