什么是 Pure Component
What are Pure Component
一句话:React.PureComponent自带一个浅比较的shouldComponentUpdate—— props 和 state 浅比较都没变就跳过渲染。 函数组件的对应物是React.memo。
「浅比较」是本题全部的考点。它对每个 prop 用Object.is 比一层。 所以:
- 传对象/数组/函数字面量 → 优化完全失效, 因为每次渲染都是新引用。
- 内部深层改了对象 → 不会重渲染, 因为引用没变 —— 界面就不更新了。
所以 PureComponent /memo 和「不可变更新」是一对: 你必须每次造新对象, 浅比较才能正确地判断出「变了」。反过来,如果你就地改对象, 加了 memo 反而会制造 bug。
会追问:「怎么让 memo 真正生效?」—— 对象和数组用 useMemo、 函数用 useCallback稳住引用。三个必须配套用, 只加 memo 往往一点用没有 (见 #346)。
「是不是所有组件都该 memo?」—— 不是。浅比较本身也有成本,props 多且经常变的组件, 加了反而更慢。
In one line: React.PureComponent ships with a shallow-comparison shouldComponentUpdate — if a shallow compare of props and state finds nothing changed, it skips the render. The function-component equivalent is React.memo.
The shallow compare is the whole point of this question. It runs Object.is on each prop, one level deep. So:
- Pass an object, array or function literal and the optimisation is dead, because every render creates a new reference.
- Mutate something deep inside an object and it will not re-render, because the reference never changed — and the UI just stops updating.
So PureComponent / memo and immutable updates come as a pair: you have to build a new object every time for the shallow compare to see a change. The reverse holds too — mutate in place and adding memo manufactures bugs.
Follow-up: “How do you make memo actually work?” — stabilise the references: useMemo for objects and arrays, useCallback for functions. The three go together; memo on its own often does nothing at all (see #346).
“Should every component be memoised?” — no. The shallow compare costs something too, so a component with many frequently changing props gets slower, not faster.