前言
使用 umi3 开发项目的过程中遇到一个常见的问题:
用户浏览 list 页面,当从 detail 页面返回到 list 页面的时候,list 重新加载了,刚刚浏览的数据又要重新去筛选,这显然不符合用户习惯。因此需要缓存之前用户浏览的 list 页面,当用户重新回来的时候渲染缓存的页面而不是重新加载。
可以使用 @alitajs/keep-alive,采用的方案,是在 layout 自己维护一份组件的显示或者隐藏,通过控制 key 变化来实现的。需要使用组件包裹 layout 的最内层。原理就是劫持了 children。
安装
yarn add @alitajs/keep-alive
或者
npm install @alitajs/keep-alive
配置
// config/config.ts
export default {
// ...
plugins:['@alitajs/keep-alive'], // 配置插件
keepalive:['/list'], // 配置需要缓存的路由
// ...
}
注意!因为是基于路由做的缓存,因此
keepalive需要配置路由
使用
// src/layouts/index.tsx
import { KeepAliveLayout } from 'umi';
const BasicLayout = props => {
return (
<OtherLayout>
<KeepAliveLayout {...props}>{props.children}</KeepAliveLayout>
</OtherLayout>
)
}
红色框是被缓存的 list 页面,蓝色框是 detail 页面。当从 list 进入到 detail,list 页面并没有被销毁,而是被隐藏了,重新回到 list 页面只需要去掉隐藏,如此实现页面缓存。
解除缓存
// src/pages/list/index.tsx
import { dropByCacheKey } from 'umi';
const Page: React.FC = props => {
return (
<div
onClick={()=>{
dropByCacheKey('/list');
}}
>
Click dropByCacheKey
</div>
);
};
动态修改 keepalive 配置
// config 可以配置 keepalive: []
import { patchKeepAlive } from 'umi';
const Page: React.FC = (props) => {
return (
<div
onClick={() => {
patchKeepAlive((config) => {
// 这里可以获取到最新的 keepalive 配置
config.push('/list');
// 更新配置之后返回
return config;
});
}}
>
Click patchKeepAlive
</div>
);
};
注意事项
@alitajs/keep-alive 是一个用于 React Web 应用中的页面缓存组件,可以将页面缓存在内存中,以提高 Web 应用的性能和用户体验。尽管这个组件有很多优点,但也存在一些缺点,例如:
- 对于某些特定的场景,页面缓存可能会带来副作用,例如在页面有动态数据、实时更新、或需要及时获取最新状态的情况下,缓存会导致用户看到过期的数据或状态。
- 当缓存的页面较多时,可能会占用较多的内存资源,从而影响应用的性能和运行稳定性。
- 组件本身的实现逻辑比较复杂,需要在组件内对路由进行监听和管理,可能会增加代码量和维护成本。
- 如果应用程序中没有对页面缓存进行有效的管理和清理,那么可能会出现缓存污染的问题,导致用户无法正常使用应用程序。
因此,在使用 @alitajs/keep-alive 组件时,需要根据具体场景进行选择和使用,避免缓存带来的副作用,并且需要在组件使用和管理上做好充分的准备和规划,以保证应用程序的性能和稳定性。