keepalive-for-react
TypeScript icon, indicating that this package has built-in type declarations

4.0.2 • Public • Published

keepalive-for-react logo

KeepAlive for React

A React KeepAlive component like keep-alive in vue

中文 | English

NPM version NPM downloads

Packages

Package Version Description
keepalive-for-react NPM version Core keepalive functionality
keepalive-for-react-router NPM version React Router integration

Features

  • Support react-router-dom v6+ or react-router v7+
  • Support React v16+ ~ v18+
  • Support Suspense and Lazy import
  • Support ErrorBoundary
  • Support Custom Container
  • Support Switching Animation Transition with className active and inactive
  • Simply implement, without any extra dependencies and hacking ways
  • Only 6KB minified size

Attention

  • DO NOT use <React.StrictMode />, it CANNOT work with keepalive-for-react in development mode. because it can lead to some unexpected behavior.

  • In Router only support react-router-dom v6+

Install

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

Usage

in react-router-dom v6+ or react-router v7+

  1. install react-router-dom v6+ or 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. use KeepAlive in your project
// 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>
    );
}

or

import { useMemo } from "react";
// v6+
import { useLocation, useOutlet } from "react-router-dom";
// v7
// import { useLocation, useOutlet } from "react-router";
import { KeepAlive, useKeepAliveRef } from "keepalive-for-react";

function Layout() {
    const location = useLocation();
    const aliveRef = useKeepAliveRef();

    const outlet = useOutlet();

    // determine which route component to is active
    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>
    );
}

details see examples/react-router-dom-simple-starter

Open in StackBlitz

in simple tabs

npm install keepalive-for-react
const tabs = [
    {
        key: "tab1",
        label: "Tab 1",
        component: Tab1,
    },
    {
        key: "tab2",
        label: "Tab 2",
        component: Tab2,
    },
    {
        key: "tab3",
        label: "Tab 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>
    );
}

details see examples/simple-tabs-starter

Open in StackBlitz

KeepAlive Props

type definition

interface KeepAliveProps {
    // determine which component to is active
    activeCacheKey: string;
    children?: KeepAliveChildren;
    /**
     * max cache count default 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;
    }>;
    /**
     * transition default false
     */
    transition?: boolean;
    /**
     * use view transition to animate the component when switching tabs
     * @see https://developer.chrome.com/docs/web-platform/view-transitions/
     */
    viewTransition?: boolean;
    /**
     * transition duration default 200
     */
    duration?: number;
    aliveRef?: RefObject<KeepAliveRef | undefined>;
    /**
     * max alive time for cache node (second)
     * @default 0 (no limit)
     */
    maxAliveTime?: number | MaxAliveConfig[];
}

interface MaxAliveConfig {
    match: string | RegExp;
    expire: number;
}

Hooks

useEffectOnActive

useEffectOnActive(() => {
    console.log("active");
}, []);

useLayoutEffectOnActive

useLayoutEffectOnActive(
    () => {
        console.log("active");
    },
    [],
    false,
);
// the third parameter is optional, default is false,
// if true, which means the callback will be skipped when the useLayoutEffect is triggered in first render

useKeepAliveContext

type definition

interface KeepAliveContext {
    /**
     * whether the component is active
     */
    active: boolean;
    /**
     * refresh the component
     * @param {string} [cacheKey] - The cache key of the component. If not provided, the current cached component will be refreshed.
     */
    refresh: (cacheKey?: string) => void;
    /**
     * destroy the component
     * @param {string} [cacheKey] - the cache key of the component, if not provided, current active cached component will be destroyed
     */
    destroy: (cacheKey?: string | string[]) => Promise<void>;
    /**
     * destroy all components
     */
    destroyAll: () => Promise<void>;
    /**
     * destroy other components except the provided cacheKey
     * @param {string} [cacheKey] - The cache key of the component. If not provided, destroy all components except the current active cached component.
     */
    destroyOther: (cacheKey?: string) => Promise<void>;
    /**
     * get the cache nodes
     */
    getCacheNodes: () => Array<CacheNode>;
}
const { active, refresh, destroy, getCacheNodes } = useKeepAliveContext();
// active is a boolean, true is active, false is inactive
// refresh is a function, you can call it to refresh the component
// destroy is a function, you can call it to destroy the component
// ...
// getCacheNodes is a function, you can call it to get the cache nodes

useKeepAliveRef

type definition

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 is a KeepAliveRef object

    // you can call refresh and destroy on aliveRef.current
    aliveRef.current?.refresh();
    // it is not necessary to call destroy manually, KeepAlive will handle it automatically
    aliveRef.current?.destroy();

    return <KeepAlive aliveRef={aliveRef}>{/* ... */}</KeepAlive>;
}
// or
function AppRouter() {
    const aliveRef = useKeepAliveRef();
    // aliveRef.current is a KeepAliveRef object

    // you can call refresh and destroy on aliveRef.current
    aliveRef.current?.refresh();
    aliveRef.current?.destroy();
    return <KeepAliveRouteOutlet aliveRef={aliveRef} />;
}

Development

install dependencies

pnpm install

build package

pnpm build

link package to global

pnpm link --global

test in demo project

cd demo
pnpm link --global keepalive-for-react

Versions

Current Tags

VersionDownloads (Last 7 Days)Tag
4.0.2339latest

Version History

VersionDownloads (Last 7 Days)Published
4.0.2339
4.0.11
4.0.0625
3.0.10144
3.0.90
3.0.8105
3.0.753
3.0.635
3.0.50
3.0.40
3.0.31
3.0.22
3.0.10
3.0.00
2.0.1942
2.0.187
2.0.171
2.0.160
2.0.150
2.0.141
2.0.132
2.0.1248
2.0.110
2.0.100
2.0.93
2.0.819
2.0.7170
2.0.60
2.0.51
2.0.40
2.0.30
2.0.20
2.0.10
2.0.00
1.0.225
1.0.211
1.0.200
1.0.191
1.0.180
1.0.171
1.0.160
1.0.151
1.0.140
1.0.131
1.0.120
1.0.110
1.0.100
1.0.90
1.0.80
1.0.7-01
1.0.70
1.0.60
1.0.50
1.0.40
1.0.30
1.0.21
1.0.11
1.0.00

Package Sidebar

Install

npm i keepalive-for-react

Weekly Downloads

1,612

Version

4.0.2

License

MIT

Unpacked Size

68.5 kB

Total Files

18

Last publish

Collaborators

  • wongyichen