手写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>
      ))}
    </>
  );
};

总结

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

相关推荐
康小汪7 小时前
AI 写 Vue 总写成同一个味道:给它装 Skills,装的不是知识是边界
前端·vue.js·人工智能·ai编程·最佳实践
智能运维指南7 小时前
研制过程“两张皮“怎么破:研制一体化支撑平台的定位、能力边界与落地前提
java·前端·人工智能·嘉为蓝鲸
白山编程大哥9 小时前
Java 后端如何优雅地把 List 集合返回给前端
java·前端·list
Flynt10 小时前
我把热榜那篇"禁用 axios"逐条实测了一遍:结论大体对,坑在它没讲的地方
前端·javascript·axios
考研保研资料分享10 小时前
四非会计保研中国矿大(北京):七场考核、候补与择校复盘
面试
Csvn10 小时前
bundle优化
前端
北冥有鱼11 小时前
发版后动态路由点击报 `Failed to fetch dynamically imported module`」问题上的完整排查与修复过程
前端·vue.js
静默回滚11 小时前
视频压到 25 MB 以内,码率要算、音轨要扣、余量要留
前端
用户372037492601811 小时前
把 10MB 中文语义模型塞进浏览器:STSB 做到教师模型的 93%,但线上 top1 只有 42%
前端
光锥智能11 小时前
海康机器人举行2026移动机器人新品发布会:箱式存拣升级,「明智」系列发布
java·前端·机器人