keepalive-for-react v4.0.2
English | 中文
包信息
包名 | 版本 | 描述 |
---|---|---|
keepalive-for-react | 核心keepalive功能 | |
keepalive-for-react-router | React Router集成 |
特性
- 支持react-router-dom v6+ 或 react-router v7+
- 支持React v16+ ~ v18+
- 支持Suspense和懒加载导入
- 支持错误边界
- 支持自定义容器
- 支持使用className
active
和inactive
进行切换动画过渡 - 简单实现,无需任何额外依赖和hack方式
- 压缩后仅6KB大小
注意事项
请勿使用 <React.StrictMode />,它在开发模式下无法与keepalive-for-react一起工作。因为它可能会导致一些意外行为。
在路由中仅支持react-router-dom v6+
安装
npm install keepalive-for-react
yarn add keepalive-for-react
pnpm add keepalive-for-react
使用
配合react-router-dom v6+ 或 react-router v7+使用
- 安装react-router-dom v6+ 或 react-router v7+
# v6+
npm install react-router-dom keepalive-for-react keepalive-for-react-router@1.x.x
# v7+
npm install react-router keepalive-for-react keepalive-for-react-router@2.x.x
- 在项目中使用KeepAlive
// 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 (
<div className="layout">
<KeepAliveRouteOutlet />
</div>
);
}
或者
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 (
<div className="layout">
<MemoizedScrollTop>
<KeepAlive transition aliveRef={aliveRef} activeCacheKey={currentCacheKey} max={18}>
<Suspense fallback={<LoadingArea />}>
<SpreadArea>{outlet}</SpreadArea>
</Suspense>
</KeepAlive>
</MemoizedScrollTop>
</div>
);
}
详情请参见 examples/react-router-dom-simple-starter
在简单标签页中
npm install keepalive-for-react
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<string>("tab1");
const tab = useMemo(() => {
return tabs.find(tab => tab.key === currentTab);
}, [currentTab]);
return (
<div>
{/* ... */}
<KeepAlive transition={true} activeCacheKey={currentTab} exclude={["tab3"]}>
{tab && <tab.component />}
</KeepAlive>
</div>
);
}
详情请参见 examples/simple-tabs-starter
KeepAlive 属性
类型定义
interface KeepAliveProps {
// 确定哪个组件处于活动状态
activeCacheKey: string;
children?: KeepAliveChildren;
/**
* 最大缓存数量 默认10
*/
max?: number;
exclude?: Array<string | RegExp> | string | RegExp;
include?: Array<string | RegExp> | string | RegExp;
onBeforeActive?: (activeCacheKey: string) => void;
customContainerRef?: RefObject<HTMLDivElement>;
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<KeepAliveRef | undefined>;
/**
* 缓存节点最大存活时间 (秒)
* @default 0 (无限制)
*/
maxAliveTime?: number | MaxAliveConfig[];
}
interface MaxAliveConfig {
match: string | RegExp;
expire: number;
}
Hooks
useEffectOnActive
useEffectOnActive(() => {
console.log("active");
}, []);
useLayoutEffectOnActive
useLayoutEffectOnActive(
() => {
console.log("active");
},
[],
false,
);
// 第三个参数是可选的,默认为false,
// 如果为true,表示在首次渲染时触发useLayoutEffect时会跳过回调
useKeepAliveContext
类型定义
interface KeepAliveContext {
/**
* 组件是否处于活动状态
*/
active: boolean;
/**
* 刷新组件
* @param {string} [cacheKey] - 组件的缓存键。如果未提供,将刷新当前缓存的组件。
*/
refresh: (cacheKey?: string) => void;
/**
* 销毁组件
* @param {string} [cacheKey] - 组件的缓存键,如果未提供,将销毁当前活动的缓存组件。
*/
destroy: (cacheKey?: string | string[]) => Promise<void>;
/**
* 销毁所有组件
*/
destroyAll: () => Promise<void>;
/**
* 销毁除提供的cacheKey外的其他组件
* @param {string} [cacheKey] - 组件的缓存键。如果未提供,将销毁除当前活动缓存组件外的所有组件。
*/
destroyOther: (cacheKey?: string) => Promise<void>;
/**
* 获取缓存节点
*/
getCacheNodes: () => Array<CacheNode>;
}
const { active, refresh, destroy, getCacheNodes } = useKeepAliveContext();
// active 是一个布尔值,true表示活动,false表示非活动
// refresh 是一个函数,你可以调用它来刷新组件
// destroy 是一个函数,你可以调用它来销毁组件
// ...
// getCacheNodes 是一个函数,你可以调用它来获取缓存节点
useKeepAliveRef
类型定义
interface KeepAliveRef {
refresh: (cacheKey?: string) => void;
destroy: (cacheKey?: string | string[]) => Promise<void>;
destroyAll: () => Promise<void>;
destroyOther: (cacheKey?: string) => Promise<void>;
getCacheNodes: () => Array<CacheNode>;
}
function App() {
const aliveRef = useKeepAliveRef();
// aliveRef.current 是一个 KeepAliveRef 对象
// 你可以在 aliveRef.current 上调用 refresh 和 destroy
aliveRef.current?.refresh();
// 通常不需要手动调用 destroy,KeepAlive 会自动处理
aliveRef.current?.destroy();
return <KeepAlive aliveRef={aliveRef}>{/* ... */}</KeepAlive>;
}
// 或者
function AppRouter() {
const aliveRef = useKeepAliveRef();
// aliveRef.current 是一个 KeepAliveRef 对象
// 你可以在 aliveRef.current 上调用 refresh 和 destroy
aliveRef.current?.refresh();
aliveRef.current?.destroy();
return <KeepAliveRouteOutlet aliveRef={aliveRef} />;
}
开发
安装依赖
pnpm install
构建包
pnpm build
链接包到全局
pnpm link --global
在演示项目中测试
cd demo
pnpm link --global keepalive-for-react
8 months ago
9 months ago
7 months ago
9 months ago
7 months ago
8 months ago
8 months ago
8 months ago
6 months ago
6 months ago
6 months ago
7 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
10 months ago
11 months ago
11 months ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago