react-keep-alive

repository·master·Indexed 21 days ago

https://github.com/structurebuilder/react-keep-alive

A React component library (v2.5.2) that allows components to maintain their state and avoid repeated re-rendering when navigating between views. It uses the React.createPortal API to cache components outside the main application tree via a <Provider> and <KeepAlive> component. The library includes the bindLifecycle HOC for componentDidActivate and componentWillUnactivate methods, as well as the useKeepAliveEffect hook for functional components. Requires React 16.3+, or 16.8+ for Hooks support.

Tokens
3K
Snippets
12
Records
18
Agent score
76%

What's inside react-keep-alive

  1. How react-keep-alive works

    master

    Unlike solutions that use display: none | block, react-keep-alive uses the React.createPortal API.

    1. The <Provider> component is responsible for saving the component's cache and rendering the cached component outside of the application tree via a portal.
    2. The <KeepAlive> component mounts these cached components from the portal back into the location where they need to be displayed.

    This approach allows for smooth animations and full support for React Hooks, as components are not simply hidden but managed through portals.

  2. How react-keep-alive works (Concept)

    master

    Unlike many implementations that use display: none | block to hide components (which breaks CSS animations), react-keep-alive uses the React.createPortal API.

    1. The <Provider> manages a cache of components.
    2. When a component is 'hidden', it is rendered via a Portal outside the main application tree to preserve its state.
    3. The <KeepAlive> component is responsible for mounting that cached component back into the correct position in the application when it needs to be displayed.
  3. Integrate Provider with React Router

    master

    When using react-router, you must place the <Provider> inside the <Router>. Because react-keep-alive uses the modern React Context API, you must ensure you are using a recent version of react-router and react-router-dom to avoid context conflicts.

    npm install react-router@next react-router-dom@next
  4. How KeepAliveProvider manages the cache

    master

    The KeepAliveProvider maintains an internal cache object where each entry is an ICacheItem.

    Key behaviors:

    • Cache Storage: Items are stored using a unique identification string.
    • Automatic Cleanup: If the max prop is set, the provider performs a FIFO (First-In-First-Out) eviction when the cache size exceeds the limit.
    • Portal Rendering: Cached components are rendered via ReactDOM.createPortal into a storeElement managed by the provider, which keeps them alive in the DOM outside the standard component tree lifecycle.
  5. Basic Usage of Provider and KeepAlive

    master

    To use the library, you must wrap your application (or the relevant part of it) in a <Provider>. Then, wrap the components you want to cache in a <KeepAlive> component. Ensure the <KeepAlive> component is a child of the <Provider>.

    import React from 'react';
    import ReactDOM from 'react-dom';
    import {
      Provider,
      KeepAlive,
    } from 'react-keep-alive';
    import Test from './views/Test';
    
    ReactDOM.render(
      <Provider>
        <KeepAlive name="Test">
          <Test />
        </KeepAlive>
      </Provider>,
      document.getElementById('root'),
    );
  6. Use bindLifecycle for component lifecycle management

    master

    To access specialized lifecycle methods when using <KeepAlive>, wrap your component with the bindLifecycle high-level component (or use the @bindLifecycle decorator).

    This adds two new lifecycle methods:

    • componentDidActivate: Executed once after the initial mount or when transitioning from an unactivated state to an active state.
    • componentWillUnactivate: Executed when the component is being cached (moved to an unactive state).

    Note: Only one of componentWillUnactivate or componentWillUnmount will trigger. componentWillUnactivate triggers when caching is required; componentWillUnmount triggers when the component is actually unmounted without being cached.

    import React from 'react';
    import {bindLifecycle} from 'react-keep-alive';
    
    @bindLifecycle
    class Test extends React.Component {
      render() {
        return (
          <div>
            This is Test.
          </div>
        );
      }
    }
  7. Use useKeepAliveEffect hook

    master

    For functional components, use the useKeepAliveEffect hook to trigger logic when a component enters or leaves the view. Because cached components are not unmounted, standard useEffect hooks will not trigger when a component is hidden/shown via keep-alive.

    Requirement: Requires a modern version of React.

    import {useKeepAliveEffect} from 'react-keep-alive';
    
    function Test() {
      useKeepAliveEffect(() => {
        console.log("mounted");
        return () => {
          console.log("unmounted");
        };
      });
      return (
        <div>
          This is Test.
        </div>
      );
    }
  8. Use the useKeepAliveEffect hook

    master

    Standard useEffect hooks do not trigger when a component is activated/deactivated via <KeepAlive> because the component is not unmounted. To run code when a component enters or leaves the active view, use the useKeepAliveEffect hook.

    Requirement: Requires a recent version of React for Hooks support.

    import React from 'react';
    import {useKeepAliveEffect} from 'react-keep-alive';
    
    function Test() {
      useKeepAliveEffect(() => {
        console.log("mounted");
        return () => {
          console.log("unmounted");
        };
      });
      return (
        <div>
          This is Test.
        </div>
      );
    }
  9. Configure the KeepAlive component

    master

    The <KeepAlive> component wraps the children that you want to cache.

    Note: The innermost outer layer of the wrapped component must contain a real DOM tag.

    Props:

    • name: A unique identifier for the cached component. All <KeepAlive> names under the same <Provider> must be unique.
    • disabled: If set to true, caching is disabled. This configuration only takes effect when the component's status changes from unactive to active.
    • extra (v2.0.1+): Additional data that can be accessed via bindLifecycle.
  10. Configure the Provider component

    master

    The <Provider> component must be rendered at the top of your application. It manages the cache for all <KeepAlive> components within its tree.

    Props:

    • include: Only components matching this key will be cached. Accepts a string, an array of strings, or a RegExp (e.g., include="A,B", include={['A', 'B']}, or include={/A|B/}).
    • exclude: Any component matching this key will not be cached. Accepts a string, an array of strings, or a RegExp.
    • max (v2.5.2+): Sets the maximum number of items in the cache. When the limit is reached, the oldest cached value is deleted.