以下涉及到 react-router V6 以及history 5.x 大家可以访问:
[scode type="share"]
import React from 'react';
import { Router } from 'react-router-dom'
import { createHashHistory } from 'history'
export const history: any = createHashHistory();
interface HistoryRouterProps {
history: typeof history;
}
export const HistoryRouter: React.FC<HistoryRouterProps> = ({ history, children }) => {
const [state, setState] = React.useState({
action: history.action,
location: history.location
})
React.useLayoutEffect(() => {
history.listen(setState);
},[history])
return React.createElement(Router, Object.assign({ children, navigator: history }, state))
}
这里官方说明 React Router 特定history
对象发挥作用的地方。它提供了一种“侦听URL ”的方法来更改历史记录操作是否是push、pop或replace。
应用程序不需要设置自己的历史对象——这是<Router>
. 它设置这些对象之一,订阅历史堆栈中的更改,并最终在URL更改时更新其状态。这会导致应用重新渲染并显示正确的 UI。它唯一需要放入状态的是 a location
,其他一切都来自该单个对象。
所以我们自定义外层 Router
组件,监听 history 的变化,手动重新渲染页面。来实现url堆栈存储,数据持久化
渲染routes
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter } from 'react-router-dom'
import App from '@src/app'
import { history, HistoryRouter } from '@utils/router'
render(
<HistoryRouter history={history}>
<App />
</HistoryRouter>
,
document.getElementById('app')
);
跳转存储数据,使用我们封装的history,在浏览器前进、后退、刷新都不会丢失对应页面的state 数据!
import { history } from '@utils/router'
history.push('/article', {
articleId
})
获取数据
import { history } from '@utils/router'
......
const getDetail = () => {
if (history.location.state && history.location.state.articleId) {
getBlogDetail({ id: Number(history.location.state.articleId) }).then(
(res: any) => {
if (res) setData(res)
}
)
}
else history.push('/')
}
]]>