手写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 的本质是:结构稳定,样式切换

相关推荐
两个西柚呀1 小时前
js中的同步和异步,三种处理异步任务的方式
前端·javascript
牛客企业服务2 小时前
2026人才选拔新基准:AI能力考核如何重构企业招聘竞争力?
面试·ai面试·ai能力·ai coding·ai能力考核
pe7er2 小时前
软件设计不要“既要又要”
前端·后端·架构
kyriewen2 小时前
从Webpack到Vite:我们迁移了一个10万行代码的项目,总结了这7个坑
前端·webpack·vite
IT_陈寒2 小时前
Java Stream并行流的坑:我花了3小时才找到的线程安全问题
前端·人工智能·后端
小新1102 小时前
最简单但完整的 Vue 响应式示例(一个简单的计数器按钮)
前端·javascript·vue.js
Raink老师2 小时前
【AI面试临阵磨枪-94】Skill 安全:注入、越权、数据泄露、恶意代码、沙箱?
数据库·安全·面试
鹿青3 小时前
给设计稿做体检:我搓了个 Skill,专治 Figma 转代码出垃圾
前端·claude·视觉设计
陈_杨3 小时前
鸿蒙APP开发:足球战术App怎么做拖拽交互?球员拖动与路线绘制
前端