你可能不知道的React-Router

前言

一不小心想起来了账号密码, 就写点什么吧。

这一年多也是经历了裁员 -> gap year -> 找工作 -> 找到工作还没找到工作,从最开始的玩的不亦乐乎,到后面的找工作怀疑人生,只能说一手烂牌,打的更是稀烂。正好最近面试有被问到React Router的实现,其实好久没看过源码了,所以面试回来又去简单看了下。

前端路由

前端路由一般分为 hash 路由和 history 路由两种模式,hash 模式下监听 hashchange 事件,history 模式监听 popstate 事件 ,从而渲染匹配对应的视图。所以我们会认为 React-Router 大概的逻辑也会是这样,大部分的博客文章里也是这么写的,我们面试也是这么回答的。

的确,在 React-Router v6 之前的版本也确实是这么做的,但是在 React-Router v6 或者是更高的 v6.4版本中,还是有些变化和区别的,这里说的区别主要是指对于 hash 模式下的事件监听。

popstate

Note that just calling history.pushState() or history.replaceState() won't trigger a popstate event. The popstate event will be triggered by doing a browser action such as a click on the back or forward button (or calling history.back() or history.forward() in JavaScript).

Mdn 上 popstate 说点击了前进或者后退,或者调用了 history.back() 、history.forward() 会触发 popstate, 而 history.pushState()和history.replaceState() 是不会触发 popstate 事件的。

其实 修改 hash 也是会触发 popstate 事件的,可以把下面的代码在控制台里跑一下。

javascript 复制代码
window.addEventListener('hashchange', function(){
    console.log('hashchange fired!')
});

window.addEventListener('popstate', function(){
    console.log('popstate fired!')
});

location.hash = 'foo'

这是因为 location.hash 修改了 hash,也会导致 history 对象的修改,

The popstate event of the Window interface is fired when the active history entry changes while the user navigates the session history. It changes the current history entry to that of the last page the user visited or, if history.pushState() has been used to add a history entry to the history stack, that history entry is used instead.

mdn 定义 history 对象的修改就会触发 popstate 事件,所以这个流程也能说得通,但是在 IE 浏览器下 修改 hash 无法触发 popstate。

graph LR hash改变 --> history改变 --> 触发popstate

history

history 是一个单独的包,也是 React-Router 的依赖,React-Router 借助其实现不同模式的路由包括 hash 路由、history 路由、还有用于 React Native 的 memory 路由。

在 history v5 版本之前,hash 路由都是采用监听 hashchange 事件,history 监听 popstate 事件,就像我们开头说的那样。

然而在 v5 版本之后,选择使用 popstate + hashchange 双管齐下的方式去监听 hash 路由,其实最初也是没加 hashchange事件的,但是有人提了 bug 发现不兼容 IE11,所以在 IE 下特别处理了。

React-Router v6/v6+

React-Router v6.4以下还是保持了对 history 包 v5 版本的引用,就像上面所说的,v5 版本的 history 已经用 popstate 去监听 hash路由了,但是单独对不兼容的 IE 做了处理。

React-Router v6.4开始,移除了对 history 包的依赖,选择自己在内部重写了一遍(把原来 history 包的代码 CV 大法过来加以修改),在6.4版本当中,React-Router 就已经完全舍弃了 hashchange 事件,不管是 hash 路由还是 history 路由,都用 popstate 来监听事件。意味着就算你使用 React-Router 创建了 hash 路由,React-Router 也是利用 popstate 去监听你的 url 变化。这也同时意味着如果你使用 React-Router 6.4之后的版本,就无法兼容 IE。

总结

  • 修改 hash 也会触发 popstate 事件,除了 IE 浏览器。
  • 抛开兼容性,就像 React18 说的不再支持 IE, 微软本身也官宣不再维护 IE,所以现代开发也可以基于 History api 去实现 hash 路由。
  • React-Router v6 完全基于 History api 去实现 hash 路由,不仅仅是 popstate 代替 hashchange 事件去监听,内部 hash 路由的跳转修改也是直接调用的 history.pushState/replaceState 相关 api。
相关推荐
孟陬2 分钟前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
Zhao-Jichao11 分钟前
AI Prompting for Everyone 课程笔记 - P17 图像生成 Imaging Generation
前端
Highcharts.js1 小时前
智能数据分析组件Orbit 正式发布与快速上手体验教程
前端·人工智能·信息可视化·数据分析系统·highcharts·orbit·智能可视化
螺丝钉tina1 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
小天源2 小时前
智叟云集系统 · 架构与职责分层
服务器·前端·数据库
Highcharts.js4 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
薛定谔的猫-菜鸟程序员4 小时前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron
最强小杰5 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
考研保研资料分享5 小时前
2022环境工程保研北师大:三校专业追问、论文贡献与择校复盘
面试
静水leo5 小时前
使用 Whistle 拦截接口并模拟后端响应
前端