# 前言
我们可以发现 react-router 用 Link 或者 Push 跳转的时候,页面没有刷新,Url 却发生了变化,而且点击浏览器的返回按钮,页面同样没有刷新,Url 又回退了,这是为什么呢?
# 解密 - 点击返回按钮页面不刷新
# HashRouter 分析
通过 location.hash
来达到 url
变化但是页面不刷新
location.hash = hash
然后通过 onhashchange
来监听浏览器的返回事件
window.addEventListener('onhashchange', function (event) {
changeDisplayName() // 替换显示内容
})
# BrowserRouter 分析
通过 pushState 来达到 url 改变但是页面不刷新,history.push
实际上用原生的 history.pushState
来实现的,history.replace
实际上是用原生的 history.replaceState
来实现的。
changeDisplayName() // 替换显示内容
window.history.pushState(null, null, newUrl)
然后通过 popstate
来监听浏览器的返回事件
window.addEventListener('popstate', function (event) {
changeDisplayName() // 替换显示内容
})
demo:
import React, { useEffect, useState, useRef, Component } from 'react';
const MapPage = () => {
return <div>MapPage</div>
}
const RankPage = () => {
return <div>RankPage</div>
}
function ConPage() {
const [ Page, setPage ] = useState('rank');
useEffect(() => {
window.addEventListener('popstate', (event) => {
console.log("location: " + document.location + ", state: " + JSON.stringify(event.page));
let val;
if(event.page=='rank') {
val='rank'
}else{
val='map'
}
console.log('useEffect',val)
setPage(val)
});
}, [])
const _changePage = () => {
if( Page=='rank' ) {
setPage('map')
window.history.pushState({page:'map'}, null, 'http://dev.jd.com:10086/con?pId=map');
} else {
setPage('rank')
window.history.pushState({page:'rank'}, null, 'http://dev.jd.com:10086/con?pId=rank');
}
}
return (
<div>
<div onClick={_changePage} className='btnTest'> 切换路由</div>
{Page=='rank' && <RankPage />}
{Page=='map' && <MapPage />}
</div>
)
}
export default ConPage