react.memo 通过浅比较 props 跳过未变化函数组件的渲染以提升性能;仅当 props 每个字段引用相同时才复用上次结果,需配合 usememo/usecallback 避免内联对象或函数导致失效。

React.memo 主要通过**跳过对 props 未变化的函数组件的重新渲染**,来减少无效渲染,从而提升整体性能。它不是“让组件变快”,而是“让不该渲染的组件不渲染”——这在深层嵌套、高频更新或大量列表项的场景中效果尤为明显。
React.memo 的工作原理
React.memo 是一个高阶组件,会对传入的 props 进行**浅比较(shallow comparison)**:
- 如果新旧 props 的每个字段都满足
===(即值相同且引用一致),则复用上一次的渲染结果,跳过本次 render; - 只要有一个字段引用不同(比如每次创建的新对象、新函数),就会触发重新渲染;
- 它只比较 props,不关心组件内部 state 或 context 变化。
什么时候用 React.memo 才真正有效
它不是“加了就快”,而是在特定模式下才起作用:
-
子组件纯展示、无内部状态:例如
<usercard name="Alice" avatarurl="/a.jpg"></usercard>; - 父组件频繁更新,但该子组件接收的 props 实际不变:比如父组件有多个 useState,但只改了无关字段;
- 组件渲染开销大:如包含大量 DOM 节点、复杂样式或子组件树;
- 配合 useCallback / useMemo 使用:避免因内联函数或对象导致 props 引用总在变,使 memo 失效。
常见失效原因与修复方式
很多项目加了 memo 却没效果,往往是因为 props 总是“看起来一样,实则不同”:
-
传递内联对象:
<child data="{{" id: name:></child>→ 每次都是新引用;
✅ 改为用useMemo缓存:const data = useMemo(() => ({ id: 1, name: 'A' }), []); -
传递内联函数:
<child onclick="{()"> doSomething(id)} /></child>→ 每次都是新函数;
✅ 改为用useCallback:const handleClick = useCallback(() => doSomething(id), [id]); -
props 中含未稳定 key 的数组或对象:比如从 API 直接取的
items数组,没做 memo 包装;
✅ 对派生数据用useMemo处理后再传入。
搭配 useReducer 或 Context 时的注意事项
当使用全局状态(如 Context)驱动组件时,即使 props 没变,context value 更新仍会强制子组件重渲染 —— 此时仅靠 memo 不够:
- 可将 context 拆分为多个小 context(如
UserContext、ThemeContext),降低订阅粒度; - 用
useContextSelector(来自use-context-selector)或自定义 hook 精确读取所需字段; - 对消费 context 的子组件本身也使用 memo,并确保 selector 返回稳定引用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











