React-router源码—好家伙!

细读 React | React Router 路由切换原理 2022 北京冬奥会开幕式此前一直在疑惑,明明不触发popstate事件,可为什么 React Router 还能挂载对应路由的组件呢?翻了一下源码,终于知道原因了。 阅读详情

本篇文章参考以下博文

《图解React-router源码》–魔术师卡颂

前言

  最近在与前辈的交流过程中,大佬抛出来一个问题, react 路由是如何实现的?平时在学习过程中,更多的是使用,还没有研究过这东西的工作原理,今天我们就来一起挖一挖,这东西是怎么做出来的。

路由原理

  首先我们需要先有一个概念,那就是路由是怎么实现的?原理呢其实就是页面的 url 发生变化,然后去匹配路径,渲染对应组件。

  接下来如何实现?

实现步骤

  总的实现步骤可以分为3步:

  1. 如何监听 url 变化?
  2. 如何匹配 path 路径,匹配规则是什么?
  3. 如何渲染对应组件。

  核心包有两个 react-router ,reat-router-dom 。

  其中 react-router-dom 是在浏览器中使用的包,包含四个组件, BrowserRouter、Link、NavLink、HashRouter 。其他的都是引用 react-router 。

  下面举一个常用例子来看。

export default function App() {
   return (
       <BrowserRouter>
           <div>
               <Link to="/">Home</Link>
               <Link to="/about">About</Link>
               <Link to="/more">More</Link>
               <Switch>
                   <Route path="/about">
                       <About />
                   </Route>
                   <Route path="/">
                       <Home />
                   </Route>
               </Switch>
           </div>
       </BrowserRouter>
   );
}

  观察上面的代码,我们可以总结以下几点:

  1. 组件是被包裹在 <BrowserRouter> 标签里,这么做的意义是什么?
  2. <Switch> 标签作用是只匹配一个 path 路径,如何实现?
  3. <Route> 的属性中有 path 路径,内部是需要展示的组件。

  我们先通过一张图来理解以下 react-router 的流程。
在这里插入图片描述

一、监听 url 变化

  正常情况下,当 url 发生变化时,浏览器会向服务器发送请求,但是使用以下两种方法不会向服务器发送请求。

  • 基于 hash
  • 基于 history

1. 选择方式: history 或 hash

   HashRouter 先是从 history 中引用 createBrowserHistory ,然后将 history 和 children 传入到 Router 。 BrowseHistory 同理。
在这里插入图片描述

  注意: BrowseHistory 必须依赖服务器让 url 都映射到 index.html ,否则会 404 。

2. 监听 URL 的变化

  拿到对应的 history,location,match 等通过 Provider 注入到子组件中
在这里插入图片描述

二、Route 中匹配渲染组件

在这里插入图片描述
(由于 return 里面不能写 if else ,三元运算符叠加起来使用,阅读是有点麻烦)

  这代码可以分两部分理解:

  1. 是否匹配
  2. 渲染组件

1. 是否匹配

   computedMatch 是使用 Switch 包裹的子组件才有的值, Switch 的作用是从上到下开始渲染,只要匹配到一个,其他的就不匹配。所以这里会先判断 computedMatch
在这里插入图片描述

  匹配解析 path ,这里使用了第三方库 path-to-regexp
在这里插入图片描述
在这里插入图片描述
  解析规则如下:

const fn = match("/user/:id", { decode: decodeURIComponent });

fn("/user/123"); //=> { path: '/user/123', index: 0, params: { id: '123' } }
fn("/invalid"); //=> false
fn("/user/caf%C3%A9"); //=> { path: '/user/caf%C3%A9', index: 0, params: { id: 'café' } }

2. 组件渲染方式

  文档中支持三种渲染方式,分别是:

// children 方式
<Route exact path="/">
   <HomePage />
</Route>

// func 方式
<Route
   path="/blog/:slug"
   render={({ match }) => {
     // Do whatever you want with the match...
     return <div />;
   }}
/>

// component 方式
<Route path="/user/:username" component={User} />

  源码部分显示如下:
在这里插入图片描述
  这部分有点乱,需要结合流程图理解。
在这里插入图片描述
  从上面的代码我们可以看出:

  1. Router 渲染的优先级: children > component > render ,三种方式互斥,只能使用一种。
  2. 不匹配的情况下,只要 children 是函数,也会渲染
  3. component 是使用 createComponent 来创建的, 这会导致不再更新现有组件,而是直接卸载再去挂载一个新的组件。如果是使用匿名函数来传入 component ,每次 render 的时候,这个 props 都不同,会导致重新渲染挂载组件,导致性能特别差。因此,当使用匿名函数的渲染时,请使用 render 或 children 。
// 不要这么使用
<Route path="/user/:username" component={() => <User/> } />

  路由的基本功能,粗略介绍了下,具体还有很多细节优化的地方大家可以自己查看源码,继续学习。




react-router 源码及原理解析 v5版本 前言,首先为什么要做react-router源码解析呢,因为之前我们有一个需求,左侧导航栏检测到路由变化的时候展示不同的样式。由于左侧导航栏没有包裹到路由Router组件中,所以左侧导航栏无法准确监测路由发生了变化,当时我想了想可以这样解决。... 阅读详情

相关推荐

react-router4基于react-router-config的路由拆分与按需加载

继上一篇 基于react16 webpack3 搭建前端spa基础框架 react-router的4种异步加载方式 继续讲解。 项目源码guthub地址:https://github.com/wangweianger/react16-webpack3.8-onepage-base-project 这篇文章主要讲解对react-router-config的使用,达到配置路

wangweianger的博客 8920

React基础源码解析

通过build your react ,加深对框架源码的理解。

zhangyun1107892254的博客 753

浅谈react-router@4.0 使用方法和源码分析

主要介绍了浅谈react-router@4.0 使用方法和源码分析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

react源码解析

react源码解析

weixin_47964837的博客 1236

airodump-ng、aircrack-ng使用教程

wifi破解、airodump-ng、aircrack-ng脚本

ssmbyss的博客 2231

高效爬取懂车帝车型数据:从静态解析到动态反爬实战

本文详细解析了如何高效爬取懂车帝车型数据,从静态HTML解析到动态接口反爬的完整实战路径。文章重点介绍了使用浏览器开发者工具定位数据、应对CSS混淆与参数加密等反爬策略,并提供了整合静态与动态抓取逻辑的Python代码示例,帮助开发者稳健地获取结构化车型信息。

wind6的博客 937

react-router-dom源码分析

Router 组件将 history 对象通过 Context 传递给下层的 Link 和 Route 组件;点击 Link 组件触发 history 对象的更新;Route 组件监听 history 对象的变化,拿到最新的路由信息和自身的 path 进行比较,如果匹配上就去渲染 component 或 render 属性指定的组件。...

apple_2021的博客 352

SFT看这一篇就够了!万字长文:监督微调(Supervised Fine-Tuning, SFT)技术全解析【从理论到实战】

大家好,我是大 F,深耕AI算法十余年,互联网大厂技术岗。分享AI算法干货、技术心得。欢迎关注,一起探索技术的无限可能!

大F子的智能小课 711

react-router原理

自己来监听URL的改变,改变url,渲染不同的组件(页面),但是页面不要进行强制刷新(a元素不行)。history接口是HTML5新增的,它有六种模式改变URL而不刷新页面。// 执行返回操作时, 依然来到urlChange。// 获取所有的a元素, 自己来监听a元素的改变。// 1.获取router-view的DOM。// 获取router-view的DOM。原理:通过监听hashchange变化。// 监听URL的改变。// 监听URL的改变。

EmotionComputer 1189

微波技术仿真:微波谐振器分析_(2).微波谐振器理论

谐振器是一种能够在特定频率范围内存储和释放电磁能量的器件。在微波频段,谐振器通常用于滤波、频率选择和能量存储等应用。一个理想的谐振器在谐振频率下能够存储无限大的能量,但在实际应用中,由于损耗的存在,谐振器的性能会受到一定限制。微波谐振器在微波通信、雷达系统、微波测量和微波电路设计等领域中发挥着重要作用。谐振器的设计需要考虑多个因素,包括谐振频率的精确控制、损耗的最小化、频率稳定性的提高和小型化设计。通过理论分析和仿真工具的使用,可以有效优化谐振器的性能,满足实际应用的需求。

2401_87715305的博客 932

置顶必读(1) |《滚雪球学SpringBoot 3.x》· 高质量专栏介绍,你值得拥有!

《滚雪球学SpringBoot 3.x》 并不是普通的技术讲解合集,它是专为开发者精心设计的系统化学习路径。通过不断“滚动学习”,我们将带领你从基础入门到高阶应用,从理解每一行代码到设计和优化大规模分布式系统,最终帮助你成长为一位精通 spring架构 的工程师。

**My Coding Family** 12万+

react-router 快速上手教程(源码分析以及实现原理~~~)

浏览器的 URL 内容是一个很好的记录页面状态的信息。SPA 形式之前,不同的 URL 都会向服务器发送请求,然后服务器返回一个完整的 HTML 页面。 SPA 形式下,URL 路由的变化只会在 浏览器端处理,所以组装页面的任务就交给了浏览器。 此时 **react-router** 出现了,通过使用 **react-router** 以及阅读 **react-router** 源码,发现 **react-router** 不过就是基于 URL 内容变化的「**智能拼图工具**」。

乐闻世界 433

C# MES通信从入门到精通(10)——C#使用HTTP的Post和Get方法和Mes系统通信

本文详细介绍了如何利用C#完成与HTTP协议的MES系统进行通信,通过POST和GET方法实现与MES系统的交互,由高级工程师的实战经验总结,实属C#与MES通信领域的葵花宝典!

qq_34059233的博客 3412

面试官,别再问我React-Router了!每一行源码我都看过了!React-Router 源码 阅读 react router

前言 此处介绍一下React-Router的核心原理。特别细致的标点符号的不予讨论。 学前小知识 React-Router其实最核心的东西是Route组件和由统一作者开发的History库来建立的。接下来跟着镜头一起走进神秘的ßReact-Router世界吧。 已经知道怎么使用的直接跳过,到下面的源码分析去┗|`O′|┛ 嗷~~ 简单示例 一起建一个简单的示例吧。先用react官网的create-react-app脚手架弄个react出来。 npx create-react-app my-app cd my

cuandeqin2083的博客 625

基于STM32、HAL库的IP5356M快充协议芯片简介及驱动程序设计

@param hip: IP5356M句柄指针。* @param hip: IP5356M句柄指针。* @param hip: IP5356M句柄指针。* @param hip: IP5356M句柄指针。* @param hip: IP5356M句柄指针。* @param hip: IP5356M句柄指针。* @param hip: IP5356M句柄指针。* @param hip: IP5356M句柄指针。* @param hip: IP5356M句柄指针。

corlin6688的博客 1219

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

React-Router源码简析

今天来和大家解析下React-Router的源码。 React-Router是React生态中最重要的组件之一。 他提供了动态的前端路由功能,能让我们在前端应用实现,高效的SPA应用。 那么这个东西是怎么实现的呢? 我们来一起看下它的源码 Router.js constructor(props) { super(props); this.state = { location: props.history.location }; // This is a bi

黄腾霄的博客 536

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

react-router和react-router-dom区别

react-router-v4,我称之为“第四代react-router”,react-router和react-router-dom的区别是什么呢? 为什么有时候我们看到如下的写法: 写法1: import {Swtich, Route, Router, HashHistory, Link} from 'react-router-dom'; 写法2: import {Switch, R...

nqmysb的博客 2637

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

react-router/react-router-dom

最近看了react-router 源码,对react-router有了更深的理解,下面写点东西备忘:react-router-dom 是对react-router 的扩展,而两者实现路由跳转的本质依赖于一个history 插件。此history 插件 是对浏览器原生 history 的封装。

qq_24428851的博客 1054

React-Router源码解读

???? 问题背景 目前保险业务用的是react技术栈,在开发过程中遇到了两个路由相关的奇怪问题: 【示例代码】 在使用React—Router的basename功能的时候发现,无论是使用 HashRouter 还是 BrowserRouter,路由中有没有basename都能够匹配到对应的组件,哪怕我们已经给路由加上了 exact 即严格匹配规则. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PXbZgZW2-1606137379914)(https://tech-p

Sallywa的博客 1064

为什么react-router官方不提供pub-sub?use-react-router存在的理由深度解析

**use-react-router** 是一个专为 react-router v5 提供 **pub-sub(发布订阅)行为** 的 React Hook:只要路由(location)发生变化,组件就会自动重新渲染,让你随时拿到最新的 `history`、`location` 和 `match`。它精准填补了官方 Hooks 时代的空窗期,是 `withRouter` 高阶组件的 Hook 化平

gitblog_00905的博客 913

ReactJS 101生态系统解析:React周边工具链的选择与使用

React作为Facebook开源的JavaScript库,专注于构建用户界面,其生态系统已发展成为现代化Web开发的核心。本文将深入解析React周边工具链,帮助开发者理解并选择适合的工具组合,提升开发效率和应用性能。 ## 一、构建工具:Webpack与Browserify的对比 在React开发中,构建工具是项目工程化的基础。目前主流的选择包括Webpack和Browserify+Gul

gitblog_00171的博客 822

图解 React-router 源码

大家好,我是若川。欢迎加我微信 ruochuan12今天分享一篇react-router源码文章,深入理解路由的本质。微信预计阅读只需8分钟。点击下方卡片关注我,或者查看源码系列文章。阅读...

u012384510的博客 156

react 6 react-router源码 matchPath

react-router matchPath import { pathToRegexp } from "path-to-regexp"; /** * react-router * match * * @param {*} path 路径规则 * @param {*} pathname 具体的地址 * @param {*} option 相关配置 配置是一个对象,该对象中,可以出现: exact, sensitive,strict */ export default functio

共同学习,心怀感激。 2096

「源码解析 」这一次彻底弄懂react-router路由原理

写在前面:为什么要学习react-router底层源码? 为什么要弄明白整个路由流程? 笔者个人感觉学习react-router,有助于我们学习单页面应用(spa)路由跳转原理,让我们理解从history.push,到组件页面切换的全套流程,使我们在面试的时候不再为路由相关的问题发怵,废话不说,让我们开启深入react-router源码之旅吧。 一 正确理解react-router 1 理解单页面应用 什么是单页面应用? 个人理解,单页面应用是使用一个html下,一次性加载js, css等资源,所有页面.

zl_Alien的博客 1900

精读《react-snippets - Router 源码》

造轮子就是应用核心原理 + 周边功能的堆砌,所以学习成熟库的源码往往会受到非核心代码干扰,Router 这个 repo 用不到 100 行源码实现了 React Router 核心机制,很适合用来学习。精读Router 快速实现了 React Router 3 个核心 API:Router、navigate、Link,下面列出基本用法,配合理解源码实现会更方便:const...

前端精读周刊 144
上一篇: React Hook 到底是个啥?
下一篇: 页面白屏不要慌,开发工具来帮忙
不见浅诗~
博客等级 码龄7年 506粉丝 129原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值