React Router 完全指南:从基础到高级实践

目录

  1. 路由基础概念

    • 现代前端路由原理
    • React Router 核心组成
    • v6 版本重大改进
  2. 基础路由配置

    • 项目初始化与安装
    • 路由树形结构设计
    • 基本导航实现
  3. 动态路由进阶

    • URL 参数处理
    • 搜索参数管理
    • 编程式导航控制
  4. 嵌套路由体系

    • 布局路由设计模式
    • 多级路由配置实战
    • Outlet 组件深度解析
  5. 高级路由功能

    • 路由懒加载优化
    • 路由守卫与权限控制
    • 滚动行为管理
  6. 服务端集成方案

    • SSR 适配指南
    • 静态站点生成策略
    • 数据预加载模式
  7. 性能优化实践

    • 路由代码分割
    • 预加载策略
    • 缓存路由状态
  8. 常见问题解析

    • 404 页面处理
    • 重定向方案对比
    • 路由冲突解决

一、路由基础概念

1.1 前端路由演进史

javascript 复制代码
// 传统多页应用
// 每次跳转都需要整页刷新

// 现代 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 项目初始化

bash 复制代码
npm install react-router-dom@6

2.2 路由树配置

jsx 复制代码
// 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 导航实现

jsx 复制代码
// 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 参数处理

jsx 复制代码
// 路由配置
{
  path: "products/:id",
  element: <ProductDetail />,
  loader: ({ params }) => fetchProduct(params.id)
}

// 组件内获取参数
import { useParams } from 'react-router-dom';

function ProductDetail() {
  const { id } = useParams();
  // ...
}

3.2 搜索参数管理

jsx 复制代码
// 获取搜索参数
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 编程式导航

jsx 复制代码
import { useNavigate } from 'react-router-dom';

function LoginForm() {
  const navigate = useNavigate();

  const handleSubmit = async () => {
    await login();
    navigate("/dashboard", { replace: true });
  };
}

四、嵌套路由体系

4.1 布局路由设计

jsx 复制代码
// 路由配置
{
  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 多级嵌套路由

jsx 复制代码
{
  path: "users",
  element: <UserManagement />,
  children: [
    { index: true, element: <UserList /> },
    {
      path: ":userId",
      element: <UserDetail />,
      children: [
        { path: "profile", element: <Profile /> },
        { path: "security", element: <Security /> }
      ]
    }
  ]
}

五、高级路由功能

5.1 路由懒加载优化

jsx 复制代码
// 动态导入组件
const ProductList = lazy(() => import('./pages/ProductList'));

// 配置路由时使用 Suspense
{
  path: "products",
  element: (
    <Suspense fallback={<Loading />}>
      <ProductList />
    </Suspense>
  )
}

5.2 路由守卫实现

jsx 复制代码
// 高阶组件形式
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 滚动恢复方案

jsx 复制代码
// 自定义滚动行为
<Router
  scrollRestoration="manual"
  onRestoreScroll={(position, { action }) => {
    if (action === 'POP') {
      window.scrollTo(position);
    }
  }}
>
  {/* 应用内容 */}
</Router>

六、服务端集成方案

6.1 SSR 适配

javascript 复制代码
// 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 数据预加载

jsx 复制代码
// 路由配置
{
  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 代码分割策略

jsx 复制代码
// 使用 React.lazy 和 import()
const ProductDetail = lazy(
  () => import('./pages/ProductDetail')
);

// 配置路由时添加 Suspense
{
  path: "products/:id",
  element: (
    <Suspense fallback={<Spinner />}>
      <ProductDetail />
    </Suspense>
  )
}

7.2 预加载机制

jsx 复制代码
// 鼠标悬停预加载
<Link 
  to="/products/123" 
  onMouseEnter={() => import('./pages/ProductDetail')}
>
  商品详情
</Link>

八、常见问题解析

8.1 404 页面处理

jsx 复制代码
// 路由配置最后添加
{
  path: "*",
  element: <NotFoundPage />
}

8.2 重定向方案对比

jsx 复制代码
// 组件内重定向
<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 性能优化检查表

  1. 启用路由懒加载
  2. 实现代码分割
  3. 添加路由预加载
  4. 配置正确缓存策略
  5. 优化数据加载流程
  6. 使用 Suspense 边界

9.3 学习资源推荐

  • 官方文档:reactrouter.com
  • GitHub 仓库:React Training/react-router
  • 实战案例库:React Router Cookbook
  • 调试工具:React Router DevTools

通过本文的系统学习,您已经掌握了 React Router 从基础配置到企业级应用的全套技能。建议在实际项目中逐步应用这些技术,先从核心路由结构开始,逐步添加高级功能,最终构建出高性能、易维护的现代化前端路由体系。

相关推荐
码间舞2 分钟前
你不知道的pnpm!如果我的电脑上安装了nvm,切换node版本后,那么pnpm还会共享一个磁盘的npm包吗?
前端·代码规范·前端工程化
用户1512905452205 分钟前
itoa函数
前端
xiaominlaopodaren6 分钟前
“UI里就可以请求数据库”,让你陌生的 React 特性
前端·javascript·react.js
薛定谔的算法8 分钟前
JavaScript数组操作完全指南:从基础到高级
前端·javascript·算法
拜无忧9 分钟前
前端,用SVG 模仿毛笔写字绘画,defs,filter
前端·css·svg
怪可爱的地球人10 分钟前
ts的迭代器和生成器
前端
FlowGram12 分钟前
Flowgram 物料库建设思考与实践
前端
用户221520442780014 分钟前
Promise实例方法和async、await语法糖
前端·javascript
普通码农14 分钟前
uniapp开发微信小程序使用takeSnapshot截图保存分享
前端
snows_l37 分钟前
MacOS 通过Homebrew 安装nvm
前端·macos