React Router:从单页应用到前端路由

6 阅读4分钟

学习 React 时,几乎所有项目都会使用:

React Router

很多同学刚接触路由时会有一个疑问:

页面明明没有刷新

为什么 URL 变了

页面内容也变了?

想搞懂 React Router,首先要理解前端的发展历史。


多页应用时代(MPA)

早期的网站大多采用:

MPA
Multi Page Application
多页应用

例如:

首页
↓
home.html

关于页
↓
about.html

个人中心
↓
user.html

用户访问:

/home.html

服务器返回:

home.html

用户再点击:

/about.html

服务器再次返回:

about.html

整个页面重新加载。


多页应用的问题

每次跳转:

发送请求

↓

服务器返回新HTML

↓

浏览器重新渲染

因此会出现:

白屏

加载慢

用户体验差

单页应用(SPA)

后来前端进入:

SPA
Single Page Application
单页应用

模式。

特点:

整个项目只有一个HTML文件

例如 React 项目:

index.html

用户第一次进入:

http://localhost:5173

浏览器加载:

index.html

之后:

页面不再刷新

所有内容都通过 JavaScript 动态更新。


单页应用如何切换页面?

例如:

http://localhost:5173/home

显示首页。


http://localhost:5173/about

显示关于页。


http://localhost:5173/user

显示个人中心。


实际上:

HTML没有变

变的是组件

例如:

/home

↓

Home组件

/about

↓

About组件

/userUser组件

因此:

URL变化

↓

加载不同组件

↓

显示不同页面

这就是:

前端路由

什么是路由?

简单理解:

URL

↓

组件

建立映射关系。

例如:

/home

↓

Home组件

/about

↓

About组件

/userUser组件

这张映射表就叫:

路由表

页面和组件的区别

很多初学者容易混淆。


组件

组件:

页面中的一个功能模块

例如:

Header

Footer

Navbar

ProductCard

这些都属于:

普通组件

页面

页面本质也是组件。

但是:

配置了路由

例如:

Home

About

User

这些会对应 URL。

因此:

配置路由的组件

=

页面组件

React Router

React 官方推荐使用:

npm install react-router-dom

来实现前端路由。


BrowserRouter

React Router 提供:

<BrowserRouter>

作用:

开启路由功能

例如:

import { BrowserRouter } from 'react-router-dom'

root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
)

BrowserRouter 的路由模式

BrowserRouter 使用:

History模式

URL:

/home
/about
/user

更加美观。


例如:

http://localhost:5173/home

而不是:

http://localhost:5173/#/home

Routes

Routes 可以理解为:

路由出口

作用:

根据URL

决定渲染哪个组件

例如:

<Routes>

</Routes>

Route

Route 是:

单个路由配置项

例如:

<Routes>

  <Route
    path="/home"
    element={<Home />}
  />

  <Route
    path="/about"
    element={<About />}
  />

</Routes>

意思:

/home

↓

Home组件

/about

↓

About组件

完整示例

import {
  BrowserRouter,
  Routes,
  Route
} from 'react-router-dom'

function App() {

  return (

    <Routes>

      <Route
        path="/home"
        element={<Home />}
      />

      <Route
        path="/about"
        element={<About />}
      />

    </Routes>

  )

}

二级路由

实际项目经常出现:

/user

├── profile
├── order
└── setting

例如:

/user/profile

/user/order

/user/setting

这种结构称为:

嵌套路由

或者:

二级路由

Outlet

React Router 提供:

<Outlet />

作用:

子路由出口

例如:

function User(){

  return (

    <div>

      用户中心

      <Outlet />

    </div>

  )

}

访问:

/user/profile

时:

User组件

↓

Outlet

↓

Profile组件

示意图:

User

├── 导航栏
├── 用户信息
└── Outlet
      ↓
   Profile

Link

React Router 推荐使用:

<Link>

实现页面跳转。

例如:

<Link to="/home">
  首页
</Link>

效果:

点击

↓

跳转路由

↓

页面不刷新

等价于:

SPA版本的a标签

为什么不用 a 标签?

例如:

<a href="/home">
  首页
</a>

会导致:

重新请求页面

重新加载资源

失去 SPA 的优势。


因此 React 推荐:

<Link to="/home">

useNavigate

很多时候需要:

代码控制跳转

例如:

登录成功

↓

跳转首页

React Router 提供:

useNavigate()

使用:

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

function Login(){

  const navigate =
    useNavigate()

  const login = ()=>{

    navigate('/home')

  }

}

流程:

点击登录

↓

登录成功

↓

navigate('/home')

↓

跳转首页

React Router 核心流程

用户访问URL

↓

Routes匹配路由

↓

Route找到组件

↓

组件渲染

↓

页面显示

面试高频题

什么是 SPA?

Single Page Application

整个项目只有一个HTML页面

路由的作用是什么?

建立

URL

↓

组件

的映射关系

页面和组件有什么区别?

页面也是组件

配置路由的组件

称为页面组件

BrowserRouter 的作用?

开启路由功能

采用History模式

Routes 的作用?

路由出口

Route 的作用?

配置单个路由

Outlet 的作用?

二级路由出口

Link 的作用?

页面跳转

不会刷新页面

useNavigate 的作用?

编程式导航

代码控制跳转

一张图记忆

React Router

│

├── BrowserRouter
│      ↓
│   开启路由
│
├── Routes
│      ↓
│   路由出口
│
├── Route
│      ↓
│   路由配置
│
├── Outlet
│      ↓
│   二级路由出口
│
├── Link
│      ↓
│   声明式导航
│
└── useNavigate
       ↓
    编程式导航

核心口诀

多页应用:

多个HTML

每次跳转重新加载

----------------

单页应用:

一个HTML

组件切换页面

----------------

路由:

URL

↓

组件

----------------

BrowserRouter:

开启路由

History模式

----------------

Routes:

路由出口

Route:

路由配置项

Outlet:

二级路由出口

Link:

页面跳转

useNavigate:

代码跳转