You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让React.memo包裹的组件仅在初始加载时渲染一次?

核心问题

代码不生效的根本原因是将React.memo包裹的子组件定义在了父组件的函数执行体内部,这直接导致React.memo的优化逻辑完全失效:

  1. 父组件每触发一次重渲染,都会重新执行ParentComponent内部的所有代码,const ChildComponent = React.memo(...)会在每次渲染时生成一个全新的组件引用。
  2. React的虚拟DOM diff规则中,如果前后两次渲染同一位置的组件类型(引用)不一致,会直接销毁旧组件实例、重新挂载新组件,根本不会触发React.memo的自定义比较逻辑,你写的永远返回true的比较函数连执行机会都没有,自然拦不住重渲染。

除此之外当前写法还有一个潜在性能问题:传给ChildComponent的items是内联定义的对象,每次父组件渲染都会生成新的对象引用,哪怕组件定义位置正确,也会额外触发memo的比较逻辑,产生不必要的开销。

修复方案

按照以下两点调整即可实现子组件仅初始加载时渲染一次的需求:

  • 将ChildComponent的定义挪到ParentComponent外部,保证组件引用全局唯一、不会随父组件渲染变化
  • 固定传给子组件的props引用,避免每次渲染生成新的props对象

修正后的参考代码:

import React, { useMemo } from 'react';

// 子组件定义移到父组件外,保证引用稳定
const ChildComponent = React.memo(({ items }) => {
    const { param1, param2, param3 } = items;
    // 其余业务逻辑
    return (<Box>子组件内容</Box>);
}, () => true); // 自定义比较函数永远返回true,跳过所有props更新触发的重渲染

const ParentComponent = (props) => {
    // 用useMemo固化props对象的引用,空依赖数组表示仅组件初始化时生成一次
    const childItems = useMemo(() => ({
        param1: 'some val..',
        param2: 'some val..',
        param3: 'some val..',
    }), []);

    return (<Box>
        <ChildComponent items={childItems} />
        {/* 其余父组件业务内容 */}
    </Box>);
}

补充:如果子组件完全不需要接收任何动态变化的props,还有更简单的实现方式:直接把子组件的JSX节点用useMemo包裹、设置空依赖数组,存在父组件里直接渲染即可,连React.memo都不需要使用。

内容的提问来源于stack exchange,提问作者Vlado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 03:03:26