使用umi-plugin-keep-alive实现KeepAlive状态存储,
并且实现
进入下一个页面时缓存,后退页面时不缓存(卸载)
类似微信小程序的页面缓存机制
1、安装
npm install umi-plugin-keep-alive --save
// 或
yarn add umi-plugin-keep-alive
2、使用在 Layout中
import './index.less';
import { useModel, KeepAlive, history } from 'umi';
import { useEffect } from 'react';
export default function Layout(props: any) {
// 需要缓存的页面路由
const keepAliveRoutes = ['/channel', '/search'];
return (
<>
{keepAliveRoutes.includes(props?.location?.pathname || '') ? (
<KeepAlive
name={history.location.search || history.location.pathname}
when={() => {
// 根据路由的前进和后退状态去判断页面是否需要缓存,前进时缓存,后退时不缓存(卸载)。 when中的代码是在页面离开(卸载)时触发的。
return history.action != 'POP'; // true卸载时缓存,false卸载时不缓存
}}
>
<div className="ddmc-main">{props.children}</div>
</KeepAlive>
) : (
<div className="ddmc-main">{props.children}</div>
)}
</>
);
}
上面demo使用的版本:
“react”: “17.x”,
“react-dom”: “17.x”,
“react-helmet”: “^6.1.0”,
“umi”: “3.5.15”,
“umi-plugin-keep-alive”: “0.0.1-beta.35”,
3.上面如果不好用看这里
如果上面不好用,说明 KeepAlive 没有真正包裹一个完整的组件。
需要做的是将 props.children 拆出来当一个全局组件塞进去。
import './index.less';
import { useModel, KeepAlive, history } from 'umi';
import { useEffect } from 'react';
const Child = (props: any) => {
return <div className="ddmc-main">{props.children}</div>;
};
export default function Layout(props: any) {
// 需要缓存的页面路由
const keepAliveRoutes = ['/channel', '/search'];
return (
<>
{keepAliveRoutes.includes(props?.location?.pathname || '') ? (
<KeepAlive
name={history.location.search || history.location.pathname}
id={history.location.search || history.location.pathname}
when={() => {
// 根据路由的前进和后退状态去判断页面是否需要缓存,前进时缓存,后退时不缓存(卸载)。 when中的代码是在页面离开(卸载)时触发的。
return history.action != 'POP'; // true卸载时缓存,false卸载时不缓存
}}
>
{/* 为了使 KeepAlive 全局生效,需要包一层组件 */}
<Child children={props.children}></Child>
</KeepAlive>
) : (
<div className="ddmc-main">{props.children}</div>
)}
</>
);
}
此功能是基于 react-activation,更详细的可参考
https://github.com/CJY0208/react-activation/blob/master/README_CN.md