ReactNode作为组件Props时,memo与useMemo的差异及问题解析
React中memo与useMemo的区别及memo失效原因解析
核心问题
用memo包裹Icon组件后作为props传给MenuButton,MenuButton仍会重渲染;但用useMemo缓存Icon组件实例后,重渲染问题消失。这背后的核心是memo和useMemo的作用对象完全不同,以及React元素的引用变化逻辑。
代码问题分析
看你代码里的两个Icon实例:
const icon = useMemo(() => { return <BoldIcon />; }, []); const memoIcon = <MemoBoldIcon />;
- 对于
memoIcon:每次BoldButton重渲染时,<MemoBoldIcon />都会被重新创建为新的React元素对象(本质是包含组件类型、props等信息的普通对象)。即便MemoBoldIcon本身被memo包裹,它作为props传给MemoMenuButton时,引用已经发生变化。而MemoMenuButton是被memo包裹的组件,会对props做浅比较——发现iconprop的引用更新,就会触发自身重渲染。 - 对于
icon:useMemo会缓存回调返回的<BoldIcon />实例,只要依赖数组(这里是空数组)不变,每次BoldButton重渲染时,icon都是同一个引用。传给MemoMenuButton的iconprop没有变化,因此MemoMenuButton不会重渲染。
memo与useMemo的本质区别
- memo:是高阶组件,作用于整个组件。功能是当组件props经浅比较无变化时,跳过该组件的重渲染,但无法控制父组件传递props时是否创建新引用。
- useMemo:是React Hook,作用于单个值/对象。功能是缓存计算结果(包括React元素这类对象),避免每次组件渲染都重新计算或创建新对象,以此保证引用稳定性。
解决memoIcon的重渲染问题
如果想让memoIcon也能避免触发MemoMenuButton重渲染,有两种简单方式:
- 用
useMemo缓存memoIcon的引用:
const memoIcon = useMemo(() => <MemoBoldIcon />, []);
- 将
memoIcon的定义移到BoldButton组件外部(因它不依赖组件内部变量):
const MemoBoldIcon = memo(BoldIcon); const memoIcon = <MemoBoldIcon />; // 全局仅创建一次 export const BoldButton = () => { // ... 组件内部逻辑 };
内容的提问来源于stack exchange,提问作者Ugus
相关产品推荐
相关产品推荐

