为什么使用React.memo封装的Tab组件仍会随父组件重渲染?
问题根因
- 导出导入逻辑错误,React.memo实际未生效
你在Tab组件中将未包裹memo的Tab作为默认导出,包裹后的MemoizedTab是命名导出,但父组件使用默认导入拿到的还是原始未做记忆化的Tab组件,所以memo完全没起作用。 - 你猜测的
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
相关产品推荐
相关产品推荐

