学习 React 时,几乎所有项目都会使用:
React Router
很多同学刚接触路由时会有一个疑问:
页面明明没有刷新
为什么 URL 变了
页面内容也变了?
想搞懂 React Router,首先要理解前端的发展历史。
多页应用时代(MPA)
早期的网站大多采用:
objectivec
MPA
Multi Page Application
多页应用
例如:
arduino
首页
↓
home.html
关于页
↓
about.html
个人中心
↓
user.html
用户访问:
arduino
/home.html
服务器返回:
arduino
home.html
用户再点击:
bash
/about.html
服务器再次返回:
about.html
整个页面重新加载。
多页应用的问题
每次跳转:
css
发送请求
↓
服务器返回新HTML
↓
浏览器重新渲染
因此会出现:
白屏
加载慢
用户体验差
单页应用(SPA)
后来前端进入:
vbnet
SPA
Single Page Application
单页应用
模式。
特点:
css
整个项目只有一个HTML文件
例如 React 项目:
diff
index.html
用户第一次进入:
arduino
http://localhost:5173
浏览器加载:
diff
index.html
之后:
页面不再刷新
所有内容都通过 JavaScript 动态更新。
单页应用如何切换页面?
例如:
bash
http://localhost:5173/home
显示首页。
bash
http://localhost:5173/about
显示关于页。
bash
http://localhost:5173/user
显示个人中心。
实际上:
css
HTML没有变
变的是组件
例如:
arduino
/home
↓
Home组件
bash
/about
↓
About组件
sql
/user
↓
User组件
因此:
URL变化
↓
加载不同组件
↓
显示不同页面
这就是:
前端路由
什么是路由?
简单理解:
URL
↓
组件
建立映射关系。
例如:
arduino
/home
↓
Home组件
bash
/about
↓
About组件
sql
/user
↓
User组件
这张映射表就叫:
路由表
页面和组件的区别
很多初学者容易混淆。
组件
组件:
页面中的一个功能模块
例如:
css
Header
Footer
Navbar
ProductCard
这些都属于:
普通组件
页面
页面本质也是组件。
但是:
配置了路由
例如:
sql
Home
About
User
这些会对应 URL。
因此:
配置路由的组件
=
页面组件
React Router
React 官方推荐使用:
npm install react-router-dom
来实现前端路由。
BrowserRouter
React Router 提供:
xml
<BrowserRouter>
作用:
开启路由功能
例如:
javascript
import { BrowserRouter } from 'react-router-dom'
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
)
BrowserRouter 的路由模式
BrowserRouter 使用:
History模式
URL:
bash
/home
/about
/user
更加美观。
例如:
bash
http://localhost:5173/home
而不是:
bash
http://localhost:5173/#/home
Routes
Routes 可以理解为:
路由出口
作用:
根据URL
决定渲染哪个组件
例如:
xml
<Routes>
</Routes>
Route
Route 是:
单个路由配置项
例如:
ini
<Routes>
<Route
path="/home"
element={<Home />}
/>
<Route
path="/about"
element={<About />}
/>
</Routes>
意思:
arduino
/home
↓
Home组件
bash
/about
↓
About组件
完整示例
javascript
import {
BrowserRouter,
Routes,
Route
} from 'react-router-dom'
function App() {
return (
<Routes>
<Route
path="/home"
element={<Home />}
/>
<Route
path="/about"
element={<About />}
/>
</Routes>
)
}
二级路由
实际项目经常出现:
sql
/user
├── profile
├── order
└── setting
例如:
bash
/user/profile
sql
/user/order
bash
/user/setting
这种结构称为:
嵌套路由
或者:
二级路由
Outlet
React Router 提供:
xml
<Outlet />
作用:
子路由出口
例如:
javascript
function User(){
return (
<div>
用户中心
<Outlet />
</div>
)
}
访问:
bash
/user/profile
时:
sql
User组件
↓
Outlet
↓
Profile组件
示意图:
markdown
User
├── 导航栏
├── 用户信息
└── Outlet
↓
Profile
Link
React Router 推荐使用:
xml
<Link>
实现页面跳转。
例如:
ini
<Link to="/home">
首页
</Link>
效果:
点击
↓
跳转路由
↓
页面不刷新
等价于:
css
SPA版本的a标签
为什么不用 a 标签?
例如:
ini
<a href="/home">
首页
</a>
会导致:
重新请求页面
重新加载资源
失去 SPA 的优势。
因此 React 推荐:
ini
<Link to="/home">
useNavigate
很多时候需要:
代码控制跳转
例如:
登录成功
↓
跳转首页
React Router 提供:
scss
useNavigate()
使用:
javascript
import {
useNavigate
} from 'react-router-dom'
function Login(){
const navigate =
useNavigate()
const login = ()=>{
navigate('/home')
}
}
流程:
scss
点击登录
↓
登录成功
↓
navigate('/home')
↓
跳转首页
React Router 核心流程
用户访问URL
↓
Routes匹配路由
↓
Route找到组件
↓
组件渲染
↓
页面显示
面试高频题
什么是 SPA?
css
Single Page Application
整个项目只有一个HTML页面
路由的作用是什么?
建立
URL
↓
组件
的映射关系
页面和组件有什么区别?
页面也是组件
配置路由的组件
称为页面组件
BrowserRouter 的作用?
开启路由功能
采用History模式
Routes 的作用?
路由出口
Route 的作用?
配置单个路由
Outlet 的作用?
二级路由出口
Link 的作用?
页面跳转
不会刷新页面
useNavigate 的作用?
编程式导航
代码控制跳转
一张图记忆
markdown
React Router
│
├── BrowserRouter
│ ↓
│ 开启路由
│
├── Routes
│ ↓
│ 路由出口
│
├── Route
│ ↓
│ 路由配置
│
├── Outlet
│ ↓
│ 二级路由出口
│
├── Link
│ ↓
│ 声明式导航
│
└── useNavigate
↓
编程式导航
核心口诀
diff
多页应用:
多个HTML
每次跳转重新加载
----------------
单页应用:
一个HTML
组件切换页面
----------------
路由:
URL
↓
组件
----------------
BrowserRouter:
开启路由
History模式
----------------
Routes:
路由出口
Route:
路由配置项
Outlet:
二级路由出口
Link:
页面跳转
useNavigate:
代码跳转