Keep Alive in React

什么是 Keep Alive?

Keep Alive 是一种技术,用于在 React 中保持组件的状态,以便在用户切换页面时或者切换显示组件时,组件的状态不会丢失。

为什么需要 Keep Alive?

  • 想象一下后台管理系统,用户在页面A填写表单,然后切换到页面B查询信息,然后返回页面A继续填写,发现之前填写的表单数据丢失了。
  • 耗时的报表数据页面A,用户切换到页面B,然后返回页面A,发现报表数据页面A需要重新加载,需要再次等待报表数据加载完成。
  • 页面A展示很多数据,有很多数据请求(大部分请求响应数据结果变化不大),用户切换到B页面,然后返回A页面,发现页面A的所有数据请求都需要重新加载,需要再次等待数据请求完成。
  • 对于多标签页架构的管理系统,如果真实dom节点过多,切换页面时,会导致页面加载缓慢和卡顿,影响用户体验。

在实际项目开发中,经常会遇到上述问题,这些问题会导致用户体验不佳,甚至影响用户的工作效率。

如何实现 Keep Alive?

市面上有很多实现 Keep Alive 的方案,但大多数方法都存在一些问题,比如:

  • 兼容性差,bug多
  • 实现复杂,包体积大

经过调研,发现React createPortal 可以实现帮助实现 Keep Alive 功能。

主要原理:

将需要缓存的页面节点,通过 createPortal 渲染到一个ReactCache组件内的一个div节点中,当用户切换页面时,选择性的将ReactCache组件内的div节点append到显示容器中,实现页面缓存。

keepalive-cache
function CacheComponent(props:{active:booleancontainerRef}){
const {active,active,chidren} = props
const dom = useMemo(()=>{
return document.createElement("div")
},[])
useEffect(()=>{
if(active){
container.current.append(dom)
}
},[])
return <>{ active && createPortal(chidren,dom)} </>
}

基于此原理,实现了一个库,keepalive-for-react,欢迎大家使用。

npm install keepalive-for-react
yarn add keepalive-for-react
pnpm add keepalive-for-react

keepalive-for-react 特性

  • 支持react-router-dom v6+
  • 支持React v16+ ~ v18+
  • 支持Suspense和懒加载导入
  • 支持错误边界
  • 支持自定义容器
  • 支持使用className activeinactive进行切换动画过渡
  • 简单实现,无需任何额外依赖和hack方式
  • 压缩后仅6KB大小