你可能不知道的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。
相关推荐
芝士爱知识a6 小时前
AI 模拟面试怎么做:智蛙公考智能体多轮对话 + 实时追问的工程实现
面试·职场和发展
KaMeidebaby6 小时前
卡梅德生物技术快报|蛋白 N 端测序在重组贻贝融合蛋白表征中的应用,解决原核表达序列偏移工艺难题
前端·人工智能·物联网·算法·百度
帅次7 小时前
Android 高级工程师面试:Java 基础知识 近1年高频追问 22 题
android·java·面试
kyriewen8 小时前
我筛了 1400 个 Claude Code Skills,留下 5 个天天在用的
前端·ai编程·claude
JNX_SEMI8 小时前
AT2401C 2.4GHz 全集成射频前端单芯片技术解析
前端·单片机·嵌入式硬件·物联网·硬件工程
anOnion8 小时前
Agentic 前端开发之 实时显示 AI Agent 终端输出
前端·javascript·人工智能
随风一样自由8 小时前
【前端领域】2026最新前端领域全梳理(框架/工具/AI/跨端/底层标准/就业趋势)
前端·人工智能·前端框架
这是个栗子8 小时前
【前端性能优化】优化数据加载:用 Promise.all 从串行到并行
前端·javascript·性能优化·异步编程·前端优化·promise.all
fei_sun9 小时前
黑洞路由(Null Route/空接口路由)
服务器·前端·javascript
大爱一家盟9 小时前
告别卡点BGM同质化 2026原创卡点音乐素材下载网站 TOP5 推荐
大数据·前端·人工智能