【React】React-Router:用“快递分拣系统”玩转单页应用路由 🚀

217 阅读6分钟

React Router:用“快递分拣系统”玩转单页应用路由 🚀

一、什么是单页应用(SPA)?

想象一下,你打开一个快递分拣系统,所有的快递包裹都堆在一个仓库里(一个HTML文件),但通过分拣员(路由)的魔法,你可以快速找到目标包裹(组件)!这就是单页应用(SPA) 的核心思想:

  • 只有一个HTML文件,页面切换时不刷新整个页面。
  • 所有功能模块(首页、用户中心、商品列表)都封装成组件。
  • 路由负责根据URL路径决定显示哪个组件。

二、React Router 简介

React Router 是 React 的官方推荐快递分拣员,它让你轻松实现SPA的路由管理。

安装依赖

npm install react-router-dom

三、基础用法:从零到“第一个快递”

1. 核心三件套

  • <BrowserRouter>:快递分拣系统的总开关(使用 history 模式)。
  • <HashRouter>:兼容老浏览器的“带 # 的地址本”。
  • <Routes>:快递分拣台(路由列表)。
  • <Route>:快递分拣规则(路径与组件的映射关系)。

2. 示例代码

在App.js文件中,使用<BrowserRouter>包裹整一个路由配置。其中<Routes>包裹所有的路由列表。<Route>为最后一层,用于配置组件与路径的映射关系。

// App.js
import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import Contact from './pages/Contact';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

小拓展-- <Link />

使用<Link/>也可以实现页面的跳转,不过原理类似于HTML中的<a/>标签,这里不过多解释


四、进阶玩法:快递分拣的高级技巧

1. 路由模式选择:哈希 vs History 模式

🔹 哈希模式(HashRouter):
  • 原理:URL 带 #(如 example.com/#/about),通过 hashchange 监听变化。
  • 优点:兼容性好(支持 IE8+),无需服务器配置。
  • 缺点:URL 不美观,SEO 友好度低。
  • 使用场景:快速原型开发、静态网站托管(如 GitHub Pages)。
🔹 History 模式(BrowserRouter):
  • 原理:URL 干净(如 example.com/about),依赖 HTML5 API。
  • 优点:SEO 友好,路径更直观。
  • 缺点:需服务器配置,否则刷新会 404。
  • 使用场景:现代 Web 应用、电商平台。
🔹 如何选择?
场景推荐模式理由
快速原型开发HashRouter无需服务器配置,兼容性好
SEO 优化的电商网站BrowserRouterURL 干净,搜索引擎友好
静态网站托管(GitHub Pages)HashRouter服务器无法自定义配置
企业级管理后台BrowserRouter用户体验更好,路径更直观
🔹 代码示例
// 哈希模式
import { HashRouter } from 'react-router-dom';
<HashRouter>
  <Routes>
    <Route path="/home" element={<Home />} />
  </Routes>
</HashRouter>

// History 模式(默认)
import { BrowserRouter } from 'react-router-dom';
<BrowserRouter>
  <Routes>
    <Route path="/home" element={<Home />} />
  </Routes>
</BrowserRouter>

2. 嵌套路由:快递盒里的小包裹

假设你的“用户中心”页面需要嵌套“个人信息”和“订单列表”两个子页面:

嵌套路由时,需要在路由配置时就需要父组件路由包裹子组件路由的配置列表。

<Outlet/>为子组件的出口,需要显示时,在父组件对应位置中使用。

// App.js
import { Outlet } from 'react-router-dom'; // 子路由出口

function UserLayout() {
  return (
    <div>
      <h1>用户中心</h1>
      <Outlet /> {/* 子路由会显示在这里 */}
    </div>
  );
}

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/user" element={<UserLayout />}> {/*作为父组件包裹嵌套子组件*/}
          <Route path="profile" element={<Profile />} />
          <Route path="orders" element={<Orders />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

效果展示:

子组件切换展示

3. 动态路由:快递单号的魔法

需要根据ID显示不同的商品详情?用动态路由!

// App.js
<Route path="/product/:id" element={<ProductDetail />} />

// ProductDetail.js
import { useParams } from 'react-router-dom';

function ProductDetail() {
  const { id } = useParams(); // 获取动态参数
  return <h1>商品详情 ID: {id}</h1>;
}

常见问题 & 解决方案

1. History 模式刷新 404?
  • 原因:服务器未返回 index.html
  • 解决:配置服务器返回 index.html(以 Nginx 为例):
location / {
  try_files $uri /index.html;
}
2. 动态路由参数获取不到?
  • 原因useParams 使用位置错误。
  • 解决:确保 useParams<Route> 内部调用:
import { useParams } from 'react-router-dom';

function ProductDetail() {
  const { id } = useParams(); // 正确使用
  return <h1>商品ID: {id}</h1>;
}

五、高能技巧:快递分拣的黑科技

1. 懒加载与代码分割:快递分拣的节能模式

懒加载是一种 延迟加载资源或数据 的优化技术,其核心思想是:仅在需要时加载资源,而不是一次性加载所有内容。

这种技术广泛应用于前端开发、数据库查询、资源管理等领域,以 提高性能和用户体验

🔍 懒加载核心原理
  1. 按需加载
    • 资源(如图片、代码模块)在初始加载时不立即加载,而是在用户需要访问或使用时才加载。
  2. 减少初始负载
    • 降低首次加载时间,节省带宽和内存。
  3. 动态加载
    • 通过条件判断或用户交互(如滚动、点击)触发加载过程。
import { lazy, Suspense } from 'react';

const LazyHome = lazy(() => import('./pages/Home'));
const LazyAbout = lazy(() => import('./pages/About'));

function App() {
  return (
    <BrowserRouter>
      <Suspense fallback={<p>加载中...</p>}>
        <Routes>
          <Route path="/" element={<LazyHome />} />
          <Route path="/about" element={<LazyAbout />} />
        </Routes>
      </Suspense>
    </BrowserRouter>
  );
}
✅ 懒加载优点
  • 减少初始加载时间:用户首次访问时,只加载必要资源,提升响应速度。
  • 节省带宽和内存:避免加载未使用的资源,优化服务器和客户端性能。
  • 提升用户体验:尤其适用于移动端或大型应用,减少卡顿和等待时间。
  • 动态扩展性:按需加载资源,适合数据量大或交互复杂的场景。
⚠️ 懒加载缺点
  • 增加后续操作延迟:首次访问未加载的资源时,可能需要额外等待。
  • 实现复杂度较高:需处理加载状态、错误边界(如 Suspense)和资源回收。
  • 潜在内容闪烁:若未使用占位符,可能因加载延迟导致界面突兀变化。

2. 路由守卫:快递分拣的权限检查

假设在开发购物平台时,不会有开发者想让用户在未登录认证的情况下使用该平台。以免造成后续不必要的麻烦。

这时候路由守卫就上场了,它将不符合条件请求的过滤驱逐出去。一般配合useNavigate()使用

代码示例:

import { useNavigate } from 'react-router-dom';

function ProtectedRoute({ children }) {
  const navigate = useNavigate();
  const isAuthenticated = false; // 假设用户未登录

  useEffect(() => {
    if (!isAuthenticated) {
      navigate('/login', { replace: true }); // 如果时未登录状态访问,则遣返回登录页
    }
  }, [isAuthenticated, navigate]);

  return isAuthenticated ? children : null;
}

定义好过滤规则后,将需要过滤的组件使用<ProtectedRoute>包裹起来,就可以使用了

// 使用方式
<Route
  path="/dashboard"
  element={
    <ProtectedRoute>
      <Dashboard />
    </ProtectedRoute>
  }
/>

六、总结:快递分拣系统的终极奥义

知识点关键代码/提示
哈希模式 vs History 模式使用 HashRouterBrowserRouter,根据场景选择模式。
动态路由<Route path="/product/:id" /> + useParams() 获取参数。
嵌套路由父组件使用 <Outlet />,子路由嵌套在 <Route> 中。
404 页面<Route path="*" element={<NotFound />} /> 捕获未匹配路径。
懒加载lazy() + Suspense 按需加载组件,提升性能。
路由守卫useNavigate() + ProtectedRoute 控制权限访问。

现在你已经掌握了 React Router 的精髓!快去你的项目里优雅地切换页面吧!📦✨