标准答案

  1. React.memo 用于缓存函数组件的渲染结果,父组件重新渲染时,如果 props 浅比较没有变化,可以跳过子组件渲染。
  2. 浅比较只比较第一层引用和值,不会深度比较对象内部字段。
  3. 如果父组件每次都创建新的对象、数组或函数传给子组件,memo 很可能失效。
  4. 组件读取的 context 变化时,即使 props 没变,也可能重新渲染。
  5. 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,增加理解成本却收益很小。

作者信息