A react <KeepAlive/> component like <keep-alive/> in vue
npm install keepalive-for-react

一个类似Vue中keep-alive的React KeepAlive组件
English | 中文
 
| 包名 | 版本 | 描述 |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ----------------- |
| keepalive-for-react |  | 核心keepalive功能 |
| keepalive-for-react-router |  | React Router集成 |
- 支持react-router-dom v6+ 或 react-router v7+
- 支持React v16+ ~ v18+ (v19.2 Activity component support [v5.0.0])
- 支持Suspense和懒加载导入
- 支持错误边界
- 支持自定义容器
- 支持使用className active和inactive进行切换动画过渡
- 简单实现,无需任何额外依赖和hack方式
- 压缩后仅6KB大小
- 支持中断state Effect当组件不活动时 (v5.0.0)
- 版本兼容性:
- React 18 请使用 keepalive-for-react@4.x.x
- React 19.2+ 请使用 keepalive-for-react@5.x.x
- 请勿使用
- 在路由中仅支持react-router-dom v6+
``bash`
npm install keepalive-for-react
`bash`
yarn add keepalive-for-react
`bash`
pnpm add keepalive-for-react
1. 安装react-router-dom v6+ 或 react-router v7+
`bash`v6+
npm install react-router-dom keepalive-for-react keepalive-for-react-router@1.x.xv7+
npm install react-router keepalive-for-react keepalive-for-react-router@2.x.x
2. 在项目中使用KeepAlive
`tsx
// v6+ keepalive-for-react-router@1.x.x
// v7+ keepalive-for-react-router@2.x.x
import KeepAliveRouteOutlet from "keepalive-for-react-router";
function Layout() {
return (
或者
`tsx
import { useMemo } from "react";
import { useLocation } from "react-router-dom";
import { KeepAlive, useKeepAliveRef } from "keepalive-for-react";function Layout() {
const location = useLocation();
const aliveRef = useKeepAliveRef();
const outlet = useOutlet();
// 确定哪个路由组件处于活动状态
const currentCacheKey = useMemo(() => {
return location.pathname + location.search;
}, [location.pathname, location.search]);
return (
}>
{outlet}
);
}
`详情请参见 examples/react-router-dom-simple-starter

$3
`bash
npm install keepalive-for-react
``tsx
const tabs = [
{
key: "tab1",
label: "标签1",
component: Tab1,
},
{
key: "tab2",
label: "标签2",
component: Tab2,
},
{
key: "tab3",
label: "标签3",
component: Tab3,
},
];function App() {
const [currentTab, setCurrentTab] = useState("tab1");
const tab = useMemo(() => {
return tabs.find(tab => tab.key === currentTab);
}, [currentTab]);
return (
{/ ... /}
{tab && }
);
}
`详情请参见 examples/simple-tabs-starter

KeepAlive 属性
类型定义
`tsx
interface KeepAliveProps {
// 确定哪个组件处于活动状态
activeCacheKey: string;
children?: KeepAliveChildren;
/**
* 最大缓存数量 默认10
*/
max?: number;
exclude?: Array | string | RegExp;
include?: Array | string | RegExp;
onBeforeActive?: (activeCacheKey: string) => void;
customContainerRef?: RefObject;
cacheNodeClassName?: string;
containerClassName?: string;
errorElement?: ComponentType<{
children: ReactNode;
}>;
/**
* 过渡效果 默认false
*/
transition?: boolean; /**
* 使用view transition来过渡组件 默认false
* @see https://developer.chrome.com/docs/web-platform/view-transitions/
*/
viewTransition?: boolean;
/**
* 过渡时间 默认200ms
*/
duration?: number;
aliveRef?: RefObject;
/**
* 缓存节点最大存活时间 (秒)
* @default 0 (无限制)
*/
maxAliveTime?: number | MaxAliveConfig[];
/**
* enable Activity component from react 19+
* @default false
* Activity component can improve performance, but it will affect the transition effect
* Attention: if enable Activity component, useEffect will trigger when the component is active
*/
enableActivity?: boolean;
}
interface MaxAliveConfig {
match: string | RegExp;
expire: number;
}
`Hooks
$3
`tsx
useEffectOnActive(() => {
console.log("active");
}, []);
`$3
`tsx
useLayoutEffectOnActive(
() => {
console.log("active");
},
[],
false,
);
// 第三个参数是可选的,默认为false,
// 如果为true,表示在首次渲染时触发useLayoutEffect时会跳过回调
`$3
类型定义
`ts
interface KeepAliveContext {
/**
* 组件是否处于活动状态
*/
active: boolean;
/**
* 刷新组件
* @param {string} [cacheKey] - 组件的缓存键。如果未提供,将刷新当前缓存的组件。
*/
refresh: (cacheKey?: string) => void;
/**
* 销毁组件
* @param {string} [cacheKey] - 组件的缓存键,如果未提供,将销毁当前活动的缓存组件。
*/
destroy: (cacheKey?: string | string[]) => Promise;
/**
* 销毁所有组件
*/
destroyAll: () => Promise;
/**
* 销毁除提供的cacheKey外的其他组件
* @param {string} [cacheKey] - 组件的缓存键。如果未提供,将销毁除当前活动缓存组件外的所有组件。
*/
destroyOther: (cacheKey?: string) => Promise;
/**
* 获取缓存节点
*/
getCacheNodes: () => Array;
}
``tsx
const { active, refresh, destroy, getCacheNodes } = useKeepAliveContext();
// active 是一个布尔值,true表示活动,false表示非活动
// refresh 是一个函数,你可以调用它来刷新组件
// destroy 是一个函数,你可以调用它来销毁组件
// ...
// getCacheNodes 是一个函数,你可以调用它来获取缓存节点
`$3
类型定义
`ts
interface KeepAliveRef {
refresh: (cacheKey?: string) => void;
destroy: (cacheKey?: string | string[]) => Promise;
destroyAll: () => Promise;
destroyOther: (cacheKey?: string) => Promise;
getCacheNodes: () => Array;
}
``tsx
function App() {
const aliveRef = useKeepAliveRef();
// aliveRef.current 是一个 KeepAliveRef 对象 // 你可以在 aliveRef.current 上调用 refresh 和 destroy
aliveRef.current?.refresh();
// 通常不需要手动调用 destroy,KeepAlive 会自动处理
aliveRef.current?.destroy();
return {/ ... /} ;
}
// 或者
function AppRouter() {
const aliveRef = useKeepAliveRef();
// aliveRef.current 是一个 KeepAliveRef 对象
// 你可以在 aliveRef.current 上调用 refresh 和 destroy
aliveRef.current?.refresh();
aliveRef.current?.destroy();
return ;
}
`开发
安装依赖
`bash
pnpm install
`构建包
`bash
pnpm build
`链接包到全局
`bash
pnpm link --global
`在演示项目中测试
`bash
cd demo
pnpm link --global keepalive-for-react
``[discord-link]: https://discord.gg/ycf896w7eA
[discord-shield]: https://img.shields.io/discord/1232158668913381467?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=flat-square
[discord-shield-badge]: https://img.shields.io/discord/1232158668913381467?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=for-the-badge