10. React Router 路由配置

一、5W1H 概述

维度 内容
What 配置应用的路由规则
Why 实现多页面应用的单页路由
When 应用需要多个页面/视图时
Where 应用入口或路由配置文件
Who 所有需要路由的开发者
How <BrowserRouter><Routes><Route path="/" element={<Home />} /></Routes></BrowserRouter>

二、What - 什么是 React Router?

React Router 是 React 应用的标准路由库,用于实现单页应用(SPA)的页面导航。

安装

npm install react-router-dom

核心组件

组件 作用
BrowserRouter 使用 HTML5 history API 的路由器
HashRouter 使用 URL hash 的路由器
Routes 路由匹配容器
Route 单个路由规则
Link 声明式导航
NavLink 带激活状态的链接

三、Why - 为什么需要路由?

3.1 多页面体验

在不刷新页面的情况下切换视图。

3.2 URL 管理

保持 URL 与 UI 同步,支持浏览器前进/后退。

3.3 代码组织

按路由拆分代码,实现懒加载。


四、When - 何时使用?

场景 推荐程度 说明
多页面应用 ✅ 必需 页面切换
单页应用 ✅ 推荐 标准方案
简单演示 ❌ 可选 可用条件渲染

五、Where - 在哪里配置?

src/
├── App.jsx              # 主路由配置
├── routes/
│   ├── index.js         # 路由配置导出
│   └── PrivateRoute.jsx # 私有路由组件
├── layouts/
│   └── Layout.jsx       # 布局组件
└── pages/
    ├── Home.jsx
    ├── About.jsx
    └── Contact.jsx

六、Who - 谁需要使用?

所有需要多页面导航的 React 开发者。


七、How - 如何配置路由?

7.1 基础配置

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

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">首页</Link>
        <Link to="/about">关于</Link>
        <Link to="/contact">联系</Link>
      </nav>
      
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}

7.2 使用 NavLink(带激活样式)

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

function Navigation() {
  return (
    <nav>
      <NavLink 
        to="/" 
        className={({ isActive }) => isActive ? 'active' : ''}
      >
        首页
      </NavLink>
      
      <NavLink 
        to="/about" 
        style={({ isActive }) => ({
          color: isActive ? 'red' : 'black',
          fontWeight: isActive ? 'bold' : 'normal'
        })}
      >
        关于
      </NavLink>
      
      <NavLink to="/contact">联系</NavLink>
    </nav>
  );
}

7.3 404 页面

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

function NotFound() {
  const navigate = useNavigate();
  return (
    <div>
      <h1>404 - 页面未找到</h1>
      <button onClick={() => navigate('/')}>返回首页</button>
    </div>
  );
}

7.4 重定向

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

function App() {
  const isLoggedIn = false;

  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route 
          path="/dashboard" 
          element={isLoggedIn ? <Dashboard /> : <Navigate to="/login" />}
        />
        <Route path="/login" element={<Login />} />
        
        {/* 旧路径重定向 */}
        <Route path="/old-about" element={<Navigate to="/about" replace />} />
      </Routes>
    </BrowserRouter>
  );
}

7.5 路由配置分离

// routes/index.js
import Home from '../pages/Home';
import About from '../pages/About';
import Contact from '../pages/Contact';
import Dashboard from '../pages/Dashboard';
import Settings from '../pages/Settings';

export const routes = [
  { path: '/', element: <Home />, name: '首页' },
  { path: '/about', element: <About />, name: '关于' },
  { path: '/contact', element: <Contact />, name: '联系' },
  { path: '/dashboard', element: <Dashboard />, name: '仪表盘', requiresAuth: true },
  { path: '/settings', element: <Settings />, name: '设置', requiresAuth: true }
];

// App.jsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { routes } from './routes';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        {routes.map(route => (
          <Route 
            key={route.path} 
            path={route.path} 
            element={route.requiresAuth ? (
              <PrivateRoute>{route.element}</PrivateRoute>
            ) : route.element} 
          />
        ))}
      </Routes>
    </BrowserRouter>
  );
}

7.6 HashRouter vs BrowserRouter

// BrowserRouter - 需要服务器配置
import { BrowserRouter } from 'react-router-dom';
// URL: example.com/about

// HashRouter - 适合静态托管
import { HashRouter } from 'react-router-dom';
// URL: example.com/#/about

// 选择建议
// - 生产环境有服务器配置:BrowserRouter
// - GitHub Pages / 静态托管:HashRouter

7.7 获取当前位置信息

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

function Breadcrumb() {
  const location = useLocation();
  
  return (
    <div>
      当前位置: {location.pathname}
      搜索参数: {location.search}
      哈希: {location.hash}
      状态: {JSON.stringify(location.state)}
    </div>
  );
}

八、常见陷阱

8.1 Routes 组件必须包裹 Route

// ❌ 错误
<BrowserRouter>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
</BrowserRouter>

// ✅ 正确
<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/about" element={<About />} />
  </Routes>
</BrowserRouter>

8.2 路径顺序

// ⚠️ 注意:更具体的路径应该放在前面
<Routes>
  <Route path="/user/:id" element={<UserDetail />} />
  <Route path="/user/profile" element={<UserProfile />} />  // 会被 /user/:id 匹配
</Routes>

// ✅ 正确顺序
<Routes>
  <Route path="/user/profile" element={<UserProfile />} />
  <Route path="/user/:id" element={<UserDetail />} />
</Routes>

九、练习题

  1. 创建一个包含首页、关于、联系页面的路由配置
  2. 添加 404 页面
  3. 实现一个简单的重定向

十、小结

组件 作用
BrowserRouter 路由容器
Routes 路由匹配器
Route 路由规则
Link 导航链接
NavLink 带激活状态的链接
Navigate 重定向

更多推荐