概述
琢磨了很久,如果一个路由里的状态很多,那么如果手动将状态存到redux或者dva或者localStorage里,等路由再次渲染的时候初始化数据是非常麻烦的,但是如果只是将路由的dom节点隐藏,不从dom树中删除,那么就免去了很多数据的存取逻辑,主要的逻辑如下,技术用的是umi+reacthooks+dva+typescript。
如果不熟悉umi的项目框架可以先去学习一下umi的基础,再来看这篇文章。
创建父路由layouts布局,ui设计稿里所有的页面都是基于这个layouts父路由的子路由,我们再layouts.tsx文件下设置要缓存的子路由列表,再dva里设置routeCache.ts用来操作缓存路由实例的存取逻辑,下面是代码的实现逻辑。
1.dva下的routeCache.ts文件
import { IRouteComponentProps } from 'umi'
export interface IRouteCacheProps {
routeCaches: {
key: string;
val: any;
};
}
export default {
namespace: 'routecache',
state: {
routeCaches: {}
},
reducers: {
setRouteCaches(state: IRouteCacheProps, actions: { payload: { key: string; val: any } }) {
const { payload } = actions
const newRouteCaches = {
...state.routeCaches,
[payload.key]: payload.val
};
return {
...state,
routeCaches: newRouteCaches
}
},
clearRouteCaches(state: IRouteCacheProps){
return {
...state,
routeCaches: {}
}
}
},
subscriptions: {
setup(props: IRouteComponentProps) {
const { history } = props
history.listen((historyRes: any) => {
// console.log(historyRes)
})
}
}
}
2.layouts/layouts.tsx文件
import React, { useEffect } from 'react';
import Styles from './layouts.less'
import { useSelector, useDispatch, IRouteComponentProps } from 'umi'
import { IRouteCacheProps } from '@/models/routecache';
import { UMI } from '@/pages/keepalive/k1'
// 需要缓存的路由path
const KEEP_ALIVE_ROUTE: string[] = [
'/main/k2',
'/main/k3'
]
interface IProps {
name: string;
color: string;
[propName: string]: any;
}
export default (props: IRouteComponentProps) => {
const a: UMI.IOneProps = { name: 'string' }
const { pathname } = props.location
const CacheRouteState = useSelector((state: { routecache: IRouteCacheProps }) => state.routecache);
const dispatch = useDispatch()
useEffect(() => {
if (KEEP_ALIVE_ROUTE.includes(pathname)) {
const { routeCaches } = CacheRouteState as any;
if (!routeCaches[pathname]) {
const currentRouteIndex = props.children.props.children.findIndex((op: any)=>op.props.path===pathname)
dispatch({
type: 'routecache/setRouteCaches',
payload: {
key: pathname,
val: props.children.props.children[currentRouteIndex]
}
})
}
}
}, [pathname])
return (
<div className={Styles['layouts']}>
{/* layouts-show是展示路由的class类,layouts-hide是隐藏路由的class类 */}
{
(Object.entries(CacheRouteState.routeCaches) || []).map(([routeName, routeVal]) => {
return <div key={routeName} className={pathname === routeName ? `${Styles['layouts-show']} cache`: `${Styles['layouts-hide']} cache`}>{
routeVal.props.render()
}</div>
})
}
{
!KEEP_ALIVE_ROUTE.includes(pathname) ?
<div className={Styles['layouts-show']}>{props.children}</div> :
null
}
</div>
);
};
当然这种处理方法还是有一些弊端,如进入缓存的路由只能用visibilitychange事件,离开和进入想触发的事件还是不好处理,欢迎大佬们指点。
最后
以上就是光亮蜻蜓为你收集整理的react路由缓存实现原理的全部内容,希望文章能够帮你解决react路由缓存实现原理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复