使用useMemo与useRef避免memoized组件重渲染的差异对比
两种实现的差异分析
首先明确:在阻止ExpensiveMemoizedTree重渲染这个核心目标上,两种写法的效果是一致的——因为它们都能让style的引用保持稳定,而经过memo处理的子组件只会在props引用变化时才重渲染。
但两者存在几个细节差异:
语义贴合度不同
useMemo是React官方设计用来缓存派生值/昂贵计算结果的Hook,用它来生成静态style对象,完全符合其语义定位。useRef的核心用途是保存跨渲染周期的可变引用(比如DOM节点、计时器ID),用它存style属于“借用法”,语义上不够贴切,其他开发者看代码时可能会疑惑为什么不用更合适的useMemo。
值的可变性风险不同
useMemo返回的对象,虽然属性可以修改,但因为依赖项是空数组,下一次渲染时useMemo还是会返回最初的对象,强行修改属性容易导致状态不一致,而且这种写法本身就违背了useMemo的使用逻辑。useRef.current是可变的,如果不小心修改了style.current.color,这个变化会直接作用到子组件(但因为引用没改,子组件不会重渲染),这种隐性的修改很容易埋下难以排查的bug。
缓存稳定性有细微差别
- React官方明确说明,
useMemo的缓存不是永久的——在内存不足等极端场景下,React可能会丢弃缓存结果,重新执行回调生成新对象。不过生成简单对象的成本极低,几乎不会影响性能,这种场景也很少见。 useRef的初始值在组件首次渲染时创建,之后的所有渲染都会复用同一个引用,不存在被React主动回收的情况,稳定性更强。
- React官方明确说明,
总结
如果只是为了避免子组件重渲染,两种写法在绝大多数场景下表现一致。但从代码语义、可维护性角度,更推荐用useMemo;如果需要确保引用绝对稳定,或者有后续修改style属性但不触发重渲染的需求,可以用useRef,但一定要注意避免意外修改引用内的值。
内容的提问来源于stack exchange,提问作者Marcus Junius Brutus
相关产品推荐
相关产品推荐

