手写KeepAlive组件

一、React 默认"切换组件就会卸载"

ini 复制代码
{activeTab === 'A'
  ? <Counter name="A" />
  : <OtherCounter name="B" />
}

从 A 切到 B:A 卸载,B 挂载

因为在 React 眼里,这是两棵完全不同的树

二、KeepAlive 真正解决是:

让组件不要被卸载

组件实例始终存在于 Fiber 树里,只是隐藏

三、核心思想:缓存 children(React 元素)

scss 复制代码
if(!cache[activeId]){
  setCache((prev)=>({
    ...prev,
    [activeId]:children,
  }))
}

<Counter name="A" />本质是一个:ReactElement 对象

把这个对象保存起来

四、保存 children 就能"保活组件"

css 复制代码
Object.entries(cache).map(([id,component])=>(
  <div
    key={id}
    style={{display:id === activeId ? 'block' : 'none'}}
  >
    {component}
  </div>
))

只要 component 被渲染过一次:

perl 复制代码
React 创建 Fiber
React 创建真实 DOM
React 建立 state
React 建立 effect

之后再也没有移除它 ,只是:display:none

五、完整 KeepAlive

ini 复制代码
const KeepAlive = ({ activeId, children }) => {
  const [cache, setCache] = useState({});

  useEffect(() => {
    setCache(prev => {
      if (prev[activeId]) return prev;
      return {
        ...prev,
        [activeId]: children,
      };
    });
  }, [activeId, children]);

  return (
    <>
      {Object.entries(cache).map(([id, component]) => (
        <div
          key={id}
          style={{ display: id === activeId ? 'block' : 'none' }}
        >
          {component}
        </div>
      ))}
    </>
  );
};

总结

childrenReactElementReactElement 可以被缓存,只要 ReactElement 一直被 render,组件就不会卸载,KeepAlive 的本质是:结构稳定,样式切换

相关推荐
葫芦和十三4 小时前
图解 MongoDB 14|Cache 与淘汰:WiredTiger 的内存治理
后端·mongodb·面试
IT_陈寒8 小时前
Vue这个坑我跳了两次,原来问题出在这
前端·人工智能·后端
kyriewen8 小时前
我用 50 行代码重写了 React Router 核心,终于搞懂了前端路由原理
前端·javascript·react.js
WebInfra9 小时前
Rspack 2.1 发布:React Compiler 提速 10 倍!
前端
李明卫杭州9 小时前
CSS 媒体查询详解:一文掌握响应式设计的核心技术
前端
lichenyang4539 小时前
从 H5 按钮到 OpenHarmony 能力调用:我如何理解 ASCF 的运行链路
前端
下家10 小时前
我放弃了 Vue/React,选择自研框架
前端·前端框架
Asize10 小时前
HTML5 Canvas 基础:从按帧动画到 ECharts 数据可视化
前端·javascript·canvas
默_笙10 小时前
🎄 后端给我一堆扁平数据,我 10 行代码把它变成了树
前端·javascript
Mahut10 小时前
我用 Electron + FFmpeg 做了一个本地视频处理工作站 ClipForge
前端·ffmpeg·electron