在 React 生态中,单页应用(SPA)的开发离不开 “路由” 这一关键技术。它能让我们在不刷新页面的情况下,实现组件间的灵活切换,打造出类多页应用的体验。而 React Router 就是 React 世界里处理路由的核心工具集。在尝试手写 React Router 之前,我们需要先深入理解它的核心概念与运作逻辑。

用简单示例认识 React Router

在 React 里做单页应用,就像在一个大网页里装很多小 “页面”(其实是不同组件)。要实现点个链接,不刷新页面就切换这些小 “页面”,就得靠路由。React Router 就是干这个活儿的工具。在自己动手写 React Router 之前,咱们先结合示例,把它的关键知识和用法搞明白。

一、路由是干啥的

单页应用就一个 HTML 文件,但里面会有好几个不同的 “页面”(用不同组件展示)。路由要做两件事:

  • 不同网址对应不同组件:比如网址是
    /home
    就显示首页组件,
    /about
    就显示关于页组件。
  • 切换时不刷新页面:点来点去,浏览器不会整个重新加载,体验更流畅。

能做到这两点的,就是路由。

二、React Router 都有啥

React Router 不是一个单独的库,是一套工具:

  • react-router
    :核心库,里面是路由最基础的逻辑,像怎么匹配路径、怎么传数据这些。
  • react-router-dom
    :基于核心库,专门给浏览器用的,能处理浏览器地址栏这些事儿,我们开发网页应用主要用它。

先给项目装上它,后面示例要用:

npm install react-router-dom

三、两种路由模式

路由得看网址来选组件,有两种看网址的方式,咱们结合示例里的配置来理解。

(一)哈希路由(HashRouter)

看网址里

#

后面的内容,比如

https://xxx.com/#/home

里的

#/home

为啥用哈希?因为

#

后面的内容变了,浏览器不会刷新页面,所以兼容性很好,老浏览器也能用。如果示例里想用这种模式,只要把代码里的

BrowserRouter

换成

HashRouter

就行

(二)浏览器历史路由(BrowserRouter)

HTML5 出来后,浏览器有了新能力,能改网址还不刷新页面。

浏览器的历史记录是像栈一样存着的,还有专门的 API:

  • history.length
    :看看历史记录有多少条。
  • history.pushState
    :往历史记录里加一条新的。
  • history.replaceState
    :替换当前的历史记录。

BrowserRouter 就是用这些 API,看网址里的路径(比如

https://xxx.com/home

里的

/home

)来选组件。这种模式的网址没有

#

,看起来更干净,但得浏览器支持 HTML5 才行。咱们下面的示例就用这种模式。

四、核心组件是啥作用(附示例)

React Router 有几个关键组件,各司其职,咱们直接用一个 “首页 + 关于页” 的示例,看它们怎么配合工作:

import React from 'react';
// 从 react-router-dom 里引入需要的组件
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';

// 1. 先写两个要切换的“页面”组件
function Home() {
  return <h1>我是首页</h1>;
}
function About() {
  return <h1>我是关于页</h1>;
}

// 2. 根组件里配置路由
function App() {
  return (
    {/* (1)Router 组件:包裹整个应用,选 BrowserRouter 模式 */}
    <Router>
      <div style={{ padding: '20px' }}>
        {/* (2)Link 组件:生成导航链接,点它换地址不刷新 */}
        <Link to="/" style={{ marginRight: '20px' }}>首页</Link>
        <Link to="/about">关于页</Link>
        <hr />

        {/* (3)Switch 组件:匹配到第一个 Route 就停,不浪费性能 */}
        <Switch>
          {/* (4)Route 组件:路径和组件的“匹配规则” */}
          {/* exact 表示精确匹配根路径 /,不然 /about 也会蹭到 / 的匹配 */}
          <Route exact path="/">
            <Home /> {/* 路径匹配,就显示 Home 组件 */}
          </Route>
          {/* 匹配 /about 路径,显示 About 组件 */}
          <Route path="/about">
            <About />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

export default App;

运行这个示例,点击 “首页”“关于页” 链接,就能在不刷新页面的情况下切换组件了。下面咱们拆解每个组件的作用:

(一)Router 组件

它自己不显示东西,主要干两件事:

  • 选路由模式:示例里用
    BrowserRouter
    (还起了个别名
    Router
    ),也能换成
    HashRouter
  • 传数据:给下面的
    Route
    Link
    这些组件传递路由相关的信息,让它们能正常工作。

一般用一个 Router 把整个应用包起来,这样所有后代组件都能用上路由功能。

(二)Link 组件

专门用来做导航链接的。普通的

<a href="/about">

点击会刷新页面,而

Link

to

属性指定目标地址,点击后只会改变地址栏的内容,不会刷新页面,正好符合单页应用的需求。

(三)Route 组件

路由的 “核心匹配器”,负责把 “路径” 和 “组件” 绑在一起。关键属性看示例就能懂:

  • path
    :要匹配的网址路径,比如
    /
    对应首页,
    /about
    对应关于页。
  • exact
    :示例里给
    /
    加了这个属性,意思是 “必须完全匹配”。如果不加,访问
    /about
    时,因为
    /about
    包含
    /
    ,会先匹配到
    /
    对应的 Home 组件,就错了。
  • 组件内容:
    Route
    标签里包的组件(比如
    <Home />
    ),就是路径匹配后要显示的内容。

(四)Switch 组件

像个 “筛选器”,包裹一堆

Route

组件时,会按顺序逐个匹配,一旦找到第一个符合条件的

Route

,就会渲染它,并且停止后面的匹配。示例里如果没有

Switch

,当路径是

/about

时,虽然会匹配到

/about

对应的 About 组件,但也会因为

/

没有

exact

而匹配到 Home 组件,导致两个组件一起显示,这就乱了。

五、下一步:自己手写 React Router

现在咱们通过示例,清楚了 React Router 是怎么用

Router

定模式、

Link

做导航、

Route

配匹配、

Switch

优化筛选,最终实现单页应用路由的。接下来,咱们就动手拆解这些逻辑,一步步写出属于自己的 React Router,把这些 “用起来” 的知识,变成 “能实现” 的能力~

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐