标准答案
- React.memo 用于缓存函数组件的渲染结果,父组件重新渲染时,如果 props 浅比较没有变化,可以跳过子组件渲染。
- 浅比较只比较第一层引用和值,不会深度比较对象内部字段。
- 如果父组件每次都创建新的对象、数组或函数传给子组件,memo 很可能失效。
- 组件读取的 context 变化时,即使 props 没变,也可能重新渲染。
- React.memo 适合渲染成本较高、props 相对稳定的组件,不适合无差别包裹所有组件。
题目解析
memo 的效果取决于 props 是否稳定,以及子组件渲染成本是否值得优化。
浅比较限制意味着父组件里的内联对象和内联函数会破坏缓存效果,必要时要配合 useMemo 或 useCallback。
如果性能问题来自 state 放得太高或 context 过大,单纯加 memo 只能缓解一部分,不能解决根因。
代码示例
下面的 memo 子组件需要稳定的 items 和 onSelect 才更容易跳过无意义渲染。
TSX
const UserList = memo(function UserList({
items,
onSelect
}: {
items: User[]
onSelect: (id: string) => void
}) {
return items.map(item => (
<button key={item.id} onClick={() => onSelect(item.id)}>
{item.name}
</button>
))
})常见误区
- 认为 React.memo 会深度比较 props。
- 父组件每次传新对象或新函数,却期待 memo 自动跳过渲染。
- 组件本身很轻量也大量包 memo,增加理解成本却收益很小。