4.0.2 • Published 6 months ago

keepalive-for-react v4.0.2

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

English | 中文

NPM版本 NPM下载量

包信息

包名版本描述
keepalive-for-reactNPM版本核心keepalive功能
keepalive-for-react-routerNPM版本React Router集成

特性

  • 支持react-router-dom v6+ 或 react-router v7+
  • 支持React v16+ ~ v18+
  • 支持Suspense和懒加载导入
  • 支持错误边界
  • 支持自定义容器
  • 支持使用className activeinactive进行切换动画过渡
  • 简单实现,无需任何额外依赖和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+使用

  1. 安装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
  1. 在项目中使用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

在StackBlitz中打开

在简单标签页中

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

在StackBlitz中打开

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
3.0.4

8 months ago

3.0.3

9 months ago

3.0.10

7 months ago

3.0.2

9 months ago

3.0.8

7 months ago

3.0.7

8 months ago

3.0.6

8 months ago

3.0.5

8 months ago

4.0.1

6 months ago

4.0.0

6 months ago

4.0.2

6 months ago

3.0.9

7 months ago

3.0.1

10 months ago

3.0.0

10 months ago

2.0.15

11 months ago

2.0.16

11 months ago

2.0.13

11 months ago

2.0.14

11 months ago

2.0.12

12 months ago

2.0.19

10 months ago

2.0.17

11 months ago

2.0.18

11 months ago

2.0.11

12 months ago

2.0.9

1 year ago

2.0.10

12 months ago

2.0.8

1 year ago

2.0.7

1 year ago

2.0.6

1 year ago

2.0.5

1 year ago

2.0.4

1 year ago

2.0.3

1 year ago

2.0.2

1 year ago

2.0.1

1 year ago

2.0.0

1 year ago

1.0.22

2 years ago

1.0.21

2 years ago

1.0.19

2 years ago

1.0.18

2 years ago

1.0.20

2 years ago

1.0.17

2 years ago

1.0.16

2 years ago

1.0.15

2 years ago

1.0.14

2 years ago

1.0.13

2 years ago

1.0.12

2 years ago

1.0.11

2 years ago

1.0.10

2 years ago

1.0.9

2 years ago

1.0.8

2 years ago

1.0.7-0

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago