keepalive-for-react

repository·main·Indexed 43 days ago

https://github.com/finedaybreak/keepalive-for-react

A lightweight (6KB) utility providing a <KeepAlive/> component for React, similar to Vue's <keep-alive>. It preserves component state during unmounting caused by route changes or tab switching. Includes dedicated integration for React Router v6+ and v7+ via keepalive-for-react-router, as well as lifecycle hooks like useEffectOnActive and useEffectOnCreate for cache management.

Tokens
13K
Snippets
39
Records
45
Agent score
54%

What's inside keepalive-for-react

  1. Enable type-aware linting in ESLint

    main

    To improve production application development, you can enable type-aware lint rules by configuring parserOptions and using stricter TypeScript ESLint configurations.

    1. Update languageOptions.parserOptions to include your project's tsconfig files and the current directory.
    2. Replace tseslint.configs.recommended with tseslint.configs.recommendedTypeChecked or tseslint.configs.strictTypeChecked.
    3. (Optional) Add ...tseslint.configs.stylisticTypeChecked.

    This ensures ESLint can leverage TypeScript's type information for more accurate linting.

    export default tseslint.config({
      languageOptions: {
        // other options...
        parserOptions: {
          project: ['./tsconfig.node.json', './tsconfig.app.json'],
          tsconfigRootDir: import.meta.dirname,
        },
      },
    })
  2. Configure eslint-plugin-react for React projects

    main

    To use recommended React linting rules, install eslint-plugin-react and update your eslint.config.js. You must specify the React version in the settings object and include the plugin and its recommended rules in the configuration.

    // eslint.config.js
    import react from 'eslint-plugin-react'
    
    export default tseslint.config({
      // Set the react version
      settings: { react: { version: '18.3' } },
      plugins: {
        // Add the react plugin
        react,
      },
      rules: {
        // other rules...
        // Enable its recommended rules
        ...react.configs.recommended.rules,
        ...react.configs['jsx-runtime'].rules,
      },
    })
  3. Enable type-aware ESLint rules in the simple-tabs-starter

    main

    For production applications, it is recommended to enable type-aware linting by updating the ESLint configuration.

    1. Configure parserOptions within languageOptions to point to your tsconfig files.
    2. Replace standard recommended configs with type-checked versions:
      • Use tseslint.configs.recommendedTypeChecked or tseslint.configs.strictTypeChecked instead of tseslint.configs.recommended.
      • Optionally add ...tseslint.configs.stylisticTypeChecked.
    export default tseslint.config({
      languageOptions: {
        // other options...
        parserOptions: {
          project: ['./tsconfig.node.json', './tsconfig.app.json'],
          tsconfigRootDir: import.meta.dirname,
        },
      },
    })
  4. Configure eslint-plugin-react for the simple-tabs-starter

    main

    To use React-specific linting rules, install eslint-plugin-react and update your eslint.config.js. You must set the react.version in the settings object and include the recommended rules and jsx-runtime rules in the rules object.

    // eslint.config.js
    import react from 'eslint-plugin-react'
    
    export default tseslint.config({
      // Set the react version
      settings: { react: { version: '18.3' } },
      plugins: {
        // Add the react plugin
        react,
      },
      rules: {
        // other rules...
        // Enable its recommended rules
        ...react.configs.recommended.rules,
        ...react.configs['jsx-runtime'].rules,
      },
    })
  5. Install keepalive-for-react-router

    main

    To use KeepAlive with React Router, you must install both keepalive-for-react and keepalive-for-react-router. The version of keepalive-for-react-router you need depends on your version of React Router.

    For React Router v6+

    Use react-router-dom and keepalive-for-react-router version 1.x.x.

    For React Router v7+

    Use react-router and keepalive-for-react-router version 2.x.x.

    # For v6+
    npm install react-router-dom keepalive-for-react keepalive-for-react-router@1.x.x
    
    # For v7+
    npm install react-router keepalive-for-react keepalive-for-react-router@2.x.x
  6. Use KeepAlive with React Router (v6+ or v7+)

    main

    To integrate with React Router, you should use the keepalive-for-react-router package.

    For React Router v6+: Install react-router-dom, keepalive-for-react, and keepalive-for-react-router@1.x.x.

    For React Router v7+: Install react-router, keepalive-for-react, and keepalive-for-react-router@2.x.x.

    Option 1: Using KeepAliveRouteOutlet (Simplest)

    Use the pre-built outlet component within your layout.

    Option 2: Manual Configuration

    For more control, use the KeepAlive component with useKeepAliveRef and useLocation to manage the activeCacheKey based on the current route.

    // v6+ example
    import KeepAliveRouteOutlet from "keepalive-for-react-router";
    
    function Layout() {
        return (
            <div className="layout">
                <KeepAliveRouteOutlet />
            </div>
        );
    }
  7. Integrate KeepAlive with React Router (v6+ or v7+)

    main

    You can integrate KeepAlive with React Router in two ways:

    1. Using the dedicated router package (Easiest)

    Install the appropriate integration package based on your router version:

    • For react-router-dom v6+:
      npm install react-router-dom keepalive-for-react keepalive-for-react-router@1.x.x
    • For react-router v7+:
      npm install react-router keepalive-for-react keepalive-for-react-router@2.x.x

    Then, use KeepAliveRouteOutlet in your layout component:

    import KeepAliveRouteOutlet from "keepalive-for-react-router";
    
    function Layout() {
        return (
            <div className="layout">
                <KeepAliveRouteOutlet />
            </div>
        );
    }

    2. Manual implementation with KeepAlive component

    If you need more control, use the core KeepAlive component and manage the cache key manually using the current location.

    import { useMemo } from "react";
    import { useLocation, useOutlet } from "react-router-dom"; // or "react-router" for v7
    import { KeepAlive, useKeepAliveRef } from "keepalive-for-react";
    
    function Layout() {
        const location = useLocation();
        const aliveRef = useKeepAliveRef();
        const outlet = useOutlet();
    
        // The cache key should represent the unique route/state
        const currentCacheKey = useMemo(() => {
            return location.pathname + location.search;
        }, [location.pathname, location.search]);
    
        return (
            <div className="layout">
                <KeepAlive transition aliveRef={aliveRef} activeCacheKey={currentCacheKey} max={18}>
                    <Suspense fallback={<LoadingArea />}>
                        <SpreadArea>{outlet}</SpreadArea>
                    </Suspense>
                </KeepAlive>
            </div>
        );
    }
    import KeepAliveRouteOutlet from "keepalive-for-react-router";
    
    function Layout() {
        return (
            <div className="layout">
                <KeepAliveRouteOutlet />
            </div>
        );
    }
  8. Important Compatibility and Usage Notes

    main

    Before using keepalive-for-react, observe these critical constraints:

    • React Versioning:
      • For React 18, use keepalive-for-react@4.x.x.
      • For React 19.2+, use keepalive-for-react@5.x.x.
    • Strict Mode: Do NOT use <React.StrictMode />. It causes unexpected behavior when used with this library.
    • Routing: When using with React Router, only react-router-dom v6+ is supported.
  9. Important compatibility and development warnings

    main

    Before using keepalive-for-react, note the following critical requirements:

    • React Versioning:
      • For React 18, use keepalive-for-react@4.x.x.
      • For React 19.2+, use keepalive-for-react@5.x.x.
    • StrictMode: DO NOT use <React.StrictMode /> in development mode. It causes unexpected behavior with the keepalive mechanism.
    • Router Support: The keepalive-for-react-router package only supports react-router-dom v6+.
  10. Implement KeepAlive for simple tabs

    main

    For a tabbed interface, use the KeepAlive component and provide a unique activeCacheKey corresponding to the currently selected tab.

    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(t => t.key === currentTab);
        }, [currentTab]);
    
        return (
            <div>
                {/* ... tab switching UI ... */}
                <KeepAlive transition={true} activeCacheKey={currentTab} exclude={["tab3"]}>
                    {tab && <tab.component />}
                </KeepAlive>
            </div>
        );
    }
    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(t => t.key === currentTab);
        }, [currentTab]);
    
        return (
            <div >
                <KeepAlive transition={true} activeCacheKey={currentTab} exclude={["tab3"]}>
                    {tab && <tab.component />}
                </KeepAlive>
            </div>
        );
    }