React中useMemo是否比React.memo更适合记忆组件?求解惑
React.memo 被认为“用法有误”的常见原因
你测试时React.memo能正常工作,说明你的场景里props是值类型或者引用未发生变化,但视频里的场景大概率是父组件传递了引用类型的props(比如对象、内联函数),此时React.memo的默认浅比较会失效,具体原因如下:
React.memo的默认逻辑是对props做浅比较:如果props是值类型(字符串、数字、布尔),只要值不变就不会触发子组件重渲染;但如果是引用类型(对象、数组、函数),哪怕内容完全一致,父组件每次渲染都会生成新的引用,浅比较会判定props发生变化,子组件依旧会重新渲染,这时候看起来React.memo“没起作用”。
视频里作者提到的useMemo,是两种解决思路之一:
- 正确的常规做法是配合useCallback/useMemo处理父组件传递的引用类型props:比如用useCallback包裹内联函数,用useMemo包裹对象/数组,确保父组件渲染时这些props的引用保持不变,这样React.memo的浅比较才能真正生效。
- 而用useMemo直接包裹子组件的渲染(比如
useMemo(() => <Child />, [依赖])),本质是把组件渲染结果缓存起来,只要依赖不变就复用这个结果,相当于绕过了React.memo的props比较逻辑,直接缓存整个子组件的输出。
举个典型的错误示例:
// 父组件 const Parent = () => { // 每次父组件渲染都会生成新的handleClick函数引用 const handleClick = () => console.log('click'); return <Child onClick={handleClick} />; }; // 子组件用React.memo包裹,但onClick每次都是新引用,子组件仍会重渲染 const Child = React.memo(({ onClick }) => { console.log('Child渲染'); return <button onClick={onClick}>按钮</button>; });
这种场景下只给子组件套React.memo,完全达不到记忆效果,这就是视频里作者说“用法不正确”的核心场景——只使用React.memo却未处理父组件传递的引用类型props,导致记忆逻辑失效。
对应的正确做法之一是给父组件的函数加useCallback:
const Parent = () => { // 空依赖确保函数引用始终不变 const handleClick = useCallback(() => console.log('click'), []); return <Child onClick={handleClick} />; };
或者用useMemo包裹子组件渲染(即视频里作者建议的方式):
const Parent = () => { const handleClick = () => console.log('click'); // 依赖为空时,只要父组件不卸载,子组件就不会重新渲染 const memoizedChild = useMemo(() => <Child onClick={handleClick} />, []); return memoizedChild; };
总结:React.memo本身没问题,但如果父组件传递的props存在引用类型且每次渲染都会生成新引用,仅靠React.memo无法实现记忆效果,这时候需要配合useCallback/useMemo处理props,或者直接用useMemo缓存子组件的渲染结果。视频里的作者应该是针对这种“只套React.memo却未处理props引用”的错误用法作出的判断。
内容的提问来源于stack exchange,提问作者Mirjalol
相关产品推荐
相关产品推荐

