在 Web 开发的发展历程中,页面的跳转和展示方式经历了显著的变化,其中路由机制的演变尤为关键。本文将从多页应用与单页应用的区别入手,详细介绍 React 生态中主流的路由解决方案 ------react-router-dom 的使用方法。
一、从多页应用到单页应用
1. 传统多页应用
早期的 Web 应用大多是多页应用。每一个页面都是一个独立的 HTML 文件,当用户在不同页面间跳转时,浏览器会重新请求新的 HTML 文件,页面会整体刷新。这种模式下,URL 的变化直接对应着不同的 HTML 资源。
2. 现代单页应用
随着前端技术的发展,单页应用逐渐成为主流。单页应用只有一个 HTML 文件,所有的页面内容都通过 JavaScript 动态生成和切换。当 URL 发生变化时,并不会重新加载整个页面,而是通过路由机制,将对应的组件渲染到固定的 HTML 容器中:
-
访问
http://localhost:5173/home时,将首页组件加载到 HTML 中 -
访问
http://localhost:5173/about时,将关于页组件加载到同一个 HTML 中
这种方式使得页面切换更加流畅,用户体验更接近原生应用。
二、页面与组件的区别
在单页应用的路由体系中,我们通常将 "配路由的组件" 称为 "页面",而普通的组件则用于构建页面的各个部分。简单来说,页面是可以通过 URL 直接访问的组件,是路由配置的基本单位。
三、React Router 的使用
在 React 项目中,我们通常使用 react-router-dom 来实现路由功能。首先需要安装这个库:
Bash
npm i react-router-dom
下面我们按照核心组件和 API 的使用顺序,介绍 react-router-dom 的基本用法:
1. BrowserRouter:路由模式
BrowserRouter 是 react-router-dom 提供的一种路由模式(history 模式),它使用 HTML5 的 history API 来管理路由状态。我们需要将整个应用的路由配置包裹在 BrowserRouter 中:
JavaScript
import { BrowserRouter } from 'react-router-dom'
function App() {
return (
<BrowserRouter>
{/* 路由配置和应用内容 */}
</BrowserRouter>
)
}
2. Routes:路由容器
Routes 提供了一个路由出口,它会根据当前 URL,从其子路由配置中选择匹配的路由进行渲染。可以理解为一个路由的容器,里面包含多个 Route 配置项:
JavaScript
import { BrowserRouter, Routes } from 'react-router-dom'
function App() {
return (
<BrowserRouter>
<Routes>
{/* 多个Route配置项 */}
</Routes>
</BrowserRouter>
)
}
3. Route:路由配置项
Route 用于定义 URL 路径与组件的对应关系,通过 path 属性指定 URL 路径,通过 element 属性指定对应的组件:
JavaScript
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Home from './views/home/Home'
import Login from './views/login/Login'
function App() {
return (
<BrowserRouter>
<Routes>
<Route path='/login' element={<Login />} />
<Route path='/home' element={<Home />} />
</Routes>
</BrowserRouter>
)
}
还可以通过 Navigate 组件实现路由重定向:
JavaScript
<Route path='/' element={<Navigate to="/login" />} />
对于不存在的路径,可以配置 404 页面:
JavaScript
<Route path='*' element={<h2>NOT FOUND</h2>} />
4. Outlet:二级路由出口
当我们需要实现嵌套路由(二级路由)时,Outlet 组件用于指定子路由组件的渲染位置。父组件中放置 Outlet,子路由的内容就会在这里显示:
JavaScript
// 父组件 Home.jsx
import { Outlet, Link } from 'react-router-dom'
export default function Home() {
return (
<div className="home">
{/* 其他内容 */}
<main className='content'>
<Outlet /> {/* 子路由组件会在这里渲染 */}
</main>
</div>
)
}
在路由配置中,可以这样定义嵌套路由:
JavaScript
<Route path='/home' element={<Home />}>
<Route path='class' element={<Class />} />
<Route path='leetcode' element={<LeetCode />} />
</Route>
5. Link:导航链接
Link 组件用于创建路由导航链接,类似于 HTML 中的 <a> 标签,但不会引起页面刷新,只会更新 URL 和对应的组件:
JavaScript
import { Link } from 'react-router-dom'
function Sidebar() {
return (
<ul>
<li><Link to="/home/class">课程</Link></li>
<li><Link to="/home/leetcode">算法</Link></li>
</ul>
)
}
6. useNavigate:编程式导航
useNavigate 是一个 React Hook,用于在代码中实现路由跳转(编程式导航),比如在登录成功后跳转到首页:
JavaScript
import { useNavigate } from 'react-router-dom'
export default function Login() {
const navigate = useNavigate()
const handleLogin = () => {
// 登录逻辑处理...
navigate('/home?id=123') // 登录成功后跳转到首页,携带参数
}
return (
<div>
<button onClick={handleLogin}>登录</button>
</div>
)
}
四、总结
react-router-dom 提供了一套完整的路由解决方案,通过 BrowserRouter、Routes、Route、Outlet、Link 和 useNavigate 等核心 API,我们可以轻松实现单页应用的路由功能。掌握这些基础用法,能够帮助我们构建出流畅的页面跳转体验,为用户提供更好的交互感受。