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

为什么使用React.memo封装的Tab组件仍会随父组件重渲染?

问题根因

  1. 导出导入逻辑错误,React.memo实际未生效
    你在Tab组件中将未包裹memo的Tab作为默认导出,包裹后的MemoizedTab是命名导出,但父组件使用默认导入拿到的还是原始未做记忆化的Tab组件,所以memo完全没起作用。
  2. 你猜测的setSelectTab每次渲染生成新实例是错误的:React 中useState返回的更新函数在组件挂载的整个生命周期内都是稳定的,不会随父组件重渲染改变。

修复方案

第一步:修正导出/导入逻辑

两种方式二选一即可:

  • 方式1:修改Tab组件的默认导出为记忆化后的组件
// Tab组件文件,修改导出部分
const Tab = ({ title, tab, setSelectTab }) => {
  // 组件逻辑不变
};
// 直接默认导出包裹memo的组件
export default React.memo(Tab);
  • 方式2:父组件改为命名导入记忆化组件
// 父组件导入修改为命名导入
import { MemoizedTab } from "./tab";

第二步(可选优化):优化子组件事件绑定,避免不必要的匿名函数生成

你当前在子组件onClick中包裹了匿名函数调用handleClick,虽然不影响memo效果,但可以优化减少函数生成:

const Tab = ({ title, tab, setSelectTab }) => {
  console.log("child render");
  // 直接在回调中使用props的tab,不需要传参
  const handleClick = useCallback(() => {
    setSelectTab(tab);
  }, [setSelectTab, tab]);
  // 直接绑定handleClick,不需要额外匿名函数
  return <p onClick={handleClick}>{title}</p>;
};

提示:如果后续需要给记忆化组件传递引用类型的props(对象、数组、普通未包裹useCallback的函数),需要用useMemo/useCallback包裹对应props,否则浅比较会判断为props变化,导致memo失效。

修复完成后,切换tab时只会打印1次parent render,未被选中的Tab组件不会触发重渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 21:24:00