React.js 实现 KeepAlive ( 使用 display:none)

相关版本号:

"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.10.0",

KeepAlive.tsx

import { memo, useEffect, useReducer, useRef } from 'react';
import { useLocation, useOutlet } from 'react-router-dom';

const KeepAlive = () => {
  // useOutlet 可以拿到当前路由要渲染的 jsx 
  // <Outlet/> 源码中就用的这个 ,我们这里给它增加一些代码,就可以把 jsx 保存起来
  const outlet = useOutlet();
  
  // 当前路由
  const { pathname } = useLocation();
  
  const componentList = useRef(new Map());
  
  // 强制渲染
  const forceUpdate = useReducer((bool: any) => !bool, true)[1]; 

  useEffect(() => {
  	// 把 jsx 存起来
    if (!componentList.current.has(pathname)) {
      componentList.current.set(pathname, outlet);      
      forceUpdate();// 刷新界面
    }

  }, [pathname]);

  // 显示当前的组件
  // 隐藏非当前的组件
  return (
    <>
      {Array.from(componentList.current).map(([key, component]) => (
        <div key={key}>
          {key === pathname ? (
            <div>{component}</div>
          ) : (
            <div style={{ display: 'none' }}>{component}</div>
          )}
        </div>
      ))}
    </>
  );
};

export default memo(KeepAlive);

使用

一个 Layout 的例子
省略了一些代码

const Index: React.FC = () => {
 
 // 使用了 antd 的这些布局组件
  return (
    <Layout>
      <Sider>        
      </Sider>
      <Layout>       
        <Content>          
            {/* ↓↓↓↓↓ 把 Outlet 换成 刚才写的 KeepAlive */}
            {/* <Outlet /> */}
            <KeepAlive/>          
        </Content>
      </Layout>
    </Layout>
  );
};

export default memo(Index);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值