Giter VIP home page Giter VIP logo

keepalive-for-react's Introduction

keepalive-for-react logo

KeepAlive for React

A React KeepAlive component like keep-alive in vue

中文 | English

NPM version NPM downloads

Attention!

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

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

Features

  • support react 16.8+ ~ 18+
  • dramatically reduce the number of dom elements in the page
  • support for caching component state
  • simply implement, without any extra dependencies and hacking ways
  • support for custom cache rules
  • high performance, no performance loss
  • easy to use, just wrap the component you want to cache

Usage

Install

npm

npm install --save keepalive-for-react 

APIs

KeepAlive

in simple tabs

import KeepAlive from 'keepalive-for-react';

function TabsPage() {
  const tabs = [
    {name: 'Tab1', cache: true, component: Tab1,},
    {name: 'Tab2', cache: true, component: Tab2,},
    {name: 'Tab3', cache: false, component: Tab3,},
  ];
  const [activeTab, setActiveTab] = useState('Tab1');

  const page = useMemo(() => {
    return tabs.find(tab => tab.name === activeTab);
  }, [activeTab]);

  return   <div>
    <KeepAlive
      max={20} strategy={'PRE'} activeName={activeTab} cache={page?.cache}
    >
      {page && <page.component name={page.name} />}
    </KeepAlive>
  </div>
}

in react-router-dom v6+

import {useLocation, useOutlet} from 'react-router-dom';

function BasicLayoutWithCache() {
  
  const outlet = useOutlet();
  const location = useLocation();


  /**
   * to distinguish different pages to cache
   */
  const cacheKey = useMemo(() => {
    return location.pathname + location.search;
  }, [location]);


  return <div>
    <KeepAlive activeName={cacheKey} max={10} strategy={'LRU'}>
      {outlet}
    </KeepAlive>
  </div>
}

useEffectOnActive / useLayoutEffectOnActive

useEffectOnActive is a hook to listen to the active state of the component which is wrapped by KeepAlive.

import {useEffectOnActive} from 'keepalive-for-react';

useEffectOnActive((active) => {
    console.log('useOnActive', active);
}, false, []);

useKeepAliveContext

useKeepAliveContext is a hook to get the KeepAlive CacheComponent context.

import {useKeepAliveContext} from 'keepalive-for-react';

function CachedComponent() {
  
  const { active, destroy} = useKeepAliveContext();
  // active: boolean, whether the component is active
  // destroy: () => void, destroy the component from cache

  // ...
}

KeepAlive Props

interface Props {
  children: ReactNode;
  /**
   * active name
   */
  activeName: string;
  /**
   * max cache count default 10
   */
  max?: number;
  /**
   * cache: boolean default true
   */
  cache?: boolean;
  /**
   * maxRemoveStrategy: 'PRE' | 'LRU' default 'PRE'
   *
   * PRE: remove the first cacheNode
   *
   * LRU: remove the least recently used cacheNode
   */
  strategy?: 'PRE' | 'LRU';
  /**
   * aliveRef: KeepAliveRef
   *
   * aliveRef is a ref to get caches, remove cache by name, clean all cache, clean other cache except current
   *
   */
  aliveRef?: RefObject<KeepAliveRef | undefined> | MutableRefObject<KeepAliveRef | undefined>;

  exclude?: Array<string | RegExp> | string | RegExp;

  include?: Array<string | RegExp> | string | RegExp;

  /**
   * suspenseElement: Suspense Wrapper Component
   */
  suspenseElement?: ComponentType<{
    children: ReactNode,
  }>;

  /**
   *  errorElement: for every cacheNode's ErrorBoundary
   */
  errorElement?: ComponentType<{
    children: ReactNode,
  }>;
}

type KeepAliveRef = {
  getCaches: () => Array<CacheNode>

  removeCache: (name: string) => Promise<void>

  cleanAllCache: () => void

  cleanOtherCache: () => void
}

useKeepaliveRef

import { useKeepaliveRef } from "keepalive-for-react"

function Example() {

    const aliveRef = useKeepaliveRef()
    
    function clean(){
        aliveRef.current?.cleanAllCache()
    }
    // ...
    
    return <KeepAlive aliveRef={aliveRef} >
        ...
    </KeepAlive>
}

Full Code Usage Example

link to React Keepalive Demo Repo

Preview Online Demo: Link: https://irychen.github.io/react-keepalive-demo/

Forum

Star History

Star History Chart

keepalive-for-react's People

Contributors

draculabo avatar irychen avatar j-sakamoto avatar yandif avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

keepalive-for-react's Issues

How to exclude/include pages to cache in router keep alive

你好!
想问一下,如果包裹的是router的useOutlet的话,可以怎么include/exclude page呢?
我下载的包版本是v2.0.0

router/index.js
  const router = createBrowserRouter([
    {
      path: '/',
      Component: Root,
      children: [
        {
          path: '/',
          element: <Home/>,
        },
        {
          path: 'product-detail/:id',
          element: <ProductDetail />
        }
      ]
    }
  ])

root.tsx
...
const outlet = useOutlet()
...
<KeepAlive aliveRef={keepAliveRef} max={5} activeName={cacheKey}>
        {outlet}
      </KeepAlive>
...

react-transition-group CSSTransition 包裹 Keepalive 不生效

目前是试过各种办法,都没有办法实现过渡和缓存效果:

  1. Keepalive 包裹 CSSTransition:这种情况会导致outlet渲染有问题,outlet渲染的是根据菜单数据动态加载的路由。
  2. 使用Keepalive包裹动态渲染的路由,这种情况下不使用CSSTransition包裹Keepalive是生效的,否则缓存无效

qiankun兼容

当{outlet}为qiankun子应用时,会导致跳转无法显示内容

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.