太棒了!👏 你已经掌握了 React 的状态管理和类型安全,现在是时候让你的应用“动起来”—— 支持多页面跳转!
—— 构建单页应用(SPA)的导航系统
🎯 目标:实现页面路由、动态路径、嵌套路由、编程式导航和权限控制。
一、为什么需要路由?🧭
在真实项目中,用户需要访问不同页面:
- 首页
/ - 用户详情
/user/123 - 博客文章
/posts/react-tutorial - 登录页
/login
而 React 是单页应用(SPA) ,不能靠刷新页面切换。
👉 所以我们需要 前端路由库 —— React Router
二、安装与基本结构
1. 安装
npm install react-router-dom
2. 基本组件
| 组件 | 作用 |
|---|---|
<BrowserRouter> | 路由根容器(使用 HTML5 History API) |
<Routes> | 包含所有路由规则 |
<Route> | 定义单条路由 |
<Link> / <NavLink> | 导航链接(不刷新页面) |
三、基础用法:静态路由 ✅
// main.tsx 或 App.tsx
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>
<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>
);
}
export default App;
✅ 注意:
path="/"是根路径element={<Component />}指定要渲染的组件
四、动态路由:参数传递 🧩
用于显示不同用户的详情、不同文章等。
示例:用户详情页 /user/:id
// routes:
<Routes>
<Route path="/" element={<Home />} />
<Route path="/user/:id" element={<UserProfile />} />
</Routes>
在组件中获取参数:
// UserProfile.tsx
import { useParams } from 'react-router-dom';
function UserProfile() {
const { id } = useParams(); // 获取动态参数
return <h2>查看用户 ID: {id}</h2>;
}
✅ 支持多个参数:
// 路径:/post/:year/:month/:day
const { year, month, day } = useParams();
五、嵌套路由:布局复用 🧱
适用于有公共布局的页面,如:
- 头部 + 侧边栏 + 内容区
- 只有内容区变化
示例:博客后台管理系统
// App.tsx
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Dashboard />} /> {/* 默认子路由 */}
<Route path="posts" element={<Posts />} />
<Route path="users" element={<Users />} />
<Route path="settings" element={<Settings />} />
</Route>
<Route path="/login" element={<Login />} />
</Routes>
Layout 组件中使用 <Outlet> 渲染子路由:
// Layout.tsx
import { Outlet, Link } from 'react-router-dom';
function Layout() {
return (
<div style={{ display: 'flex' }}>
<nav style={{ width: 200, borderRight: '1px solid #ccc' }}>
<ul>
<li><Link to="/">仪表盘</Link></li>
<li><Link to="posts">文章管理</Link></li>
<li><Link to="users">用户管理</Link></li>
</ul>
</nav>
<main style={{ padding: 20 }}>
<Outlet /> {/* 子路由在这里渲染 */}
</main>
</div>
);
}
六、编程式导航:代码跳转 ⚙️
有时候你不希望用户点击链接,而是通过逻辑控制跳转。
使用 useNavigate Hook
import { useNavigate } from 'react-router-dom';
function LoginButton() {
const navigate = useNavigate();
const handleLogin = () => {
// 模拟登录成功
console.log('登录成功');
navigate('/dashboard'); // 跳转到首页
};
return <button onClick={handleLogin}>登录</button>;
}
其他跳转方式:
navigate(-1); // 后退一页
navigate(1); // 前进一页
navigate('/search', { replace: true }); // 替换当前历史记录
七、搜索参数(Query Params)🔍
URL 中 ? 后的部分,如 /search?q=react&type=tutorial
获取 query 参数
import { useSearchParams } from 'react-router-dom';
function SearchPage() {
const [searchParams, setSearchParams] = useSearchParams();
const q = searchParams.get('q');
const type = searchParams.get('type');
const handleFilter = (newType) => {
setSearchParams({ q, type: newType });
};
return (
<div>
<p>搜索关键词:{q}</p>
<p>类型:{type}</p>
<button onClick={() => handleFilter('all')}>全部</button>
<button onClick={() => handleFilter('blog')}>博客</button>
<button onClick={() => handleFilter('video')}>视频</button>
</div>
);
}
✅ URL 自动变为:/search?q=react&type=blog
八、权限路由(私有路由)🔐
某些页面只有登录后才能访问,比如 /dashboard
创建一个受保护的路由组件
// components/PrivateRoute.tsx
import { Navigate } from 'react-router-dom';
import { useAuth } from '../hooks/useAuth'; // 假设你有一个 auth 状态
function PrivateRoute({ children }: { children: JSX.Element }) {
const { isLoggedIn } = useAuth();
if (!isLoggedIn) {
return <Navigate to="/login" replace />;
}
return children;
}
使用方式:
<Routes>
<Route path="/login" element={<Login />} />
<Route
path="/dashboard"
element={
<PrivateRoute>
<Dashboard />
</PrivateRoute>
}
/>
</Routes>
✅ 当未登录时,自动重定向到 /login
九、实战练习 🏋️♀️
✅ 练习 1:构建博客路由系统
实现以下页面和路由:
/→ 首页(文章列表)/post/:slug→ 文章详情(如/post/react-router-tutorial)/category/:name→ 分类页面/about→ 关于我们
要求:
- 使用
<Link>实现导航 - 在
PostDetail中用useParams()获取 slug 并显示标题
✅ 练习 2:带搜索功能的文章列表
- 路径:
/search - 支持
?q=关键词 - 显示“搜索结果:xxx”
- 添加输入框,回车后更新 query 参数
✅ 练习 3:登录后才能访问的个人中心
- 创建
/profile页面 - 如果未登录(可用
const isLoggedIn = false模拟),重定向到/login - 登录按钮点击后设置
isLoggedIn = true并跳转回/profile
✅ 总结:React Router v6 核心要点
| 功能 | 关键 API |
|---|---|
| 基础路由 | <BrowserRouter>, <Routes>, <Route> |
| 导航链接 | <Link>, <NavLink>(带激活样式) |
| 动态参数 | :id, useParams() |
| 嵌套路由 | <Outlet> + 父子结构 |
| 编程式导航 | useNavigate() |
| 查询参数 | useSearchParams() |
| 重定向 | <Navigate to="/path" /> |
| 权限控制 | 自定义 PrivateRoute 组件 |
🎯 下一步预告:
你已经能构建完整的多页面应用了!接下来我们要优化用户体验:
➡️ React 性能优化技巧
—— 避免不必要的渲染、懒加载组件、使用 Memo、Code Splitting
是否继续?我将带你进入 第九课:React 性能优化实战。