DrillLab
第 72 / 105 道72 / 105 · #346

React.memo vs useMemo

React.memo vs useMemo

先自己答,再往下看Answer it yourself first

一句话:React.memo 是 「组件」级的 —— 决定要不要重新渲染整个组件useMemo 是 「值」级的 —— 决定要不要重新计算一个值

React.memouseMemo
是什么高阶组件hook
用在哪包在组件外面写在组件里面
比较什么props(浅比较)依赖数组
省掉什么一次组件渲染一次计算

关键:三个必须配套用。只在子组件上加 React.memo通常一点效果都没有—— 因为父组件每次渲染都会给出新的对象和函数字面量, 浅比较必然判定「变了」。必须同时用useMemo 稳住对象、useCallback 稳住函数。

会追问:memo 能拦住 context 变化吗?」——拦不住memo 只比 props, context 走另一条通道。所以 context value 必须useMemo—— 这正是我们那道主题切换变式题的核心考点, 删掉 useMemo 后实测「功能测试全绿、 只有引用稳定性那条红」。
children 会破坏 memo 吗?」—— 会,children 也是 prop, 而 JSX 每次都产生新元素对象。

In one line: React.memo works at the “component” level — it decides whether to re-render a whole component; useMemo works at the “value” level — it decides whether to recompute one value.

React.memouseMemo
What it isA higher-order componentA hook
Where it goesWrapped around the componentInside the component
What it comparesprops (shallow)the dependency array
What it savesone component renderone computation

The key point: all three go together. Dropping React.memo on a child usually does nothing at all — the parent hands down fresh object and function literals on every render, so the shallow compare is bound to say “changed”. You must also stabilise objects with useMemo and functions with useCallback.

Follow-up: “Can memo stop a context change?” — no it cannot. memo only compares props; context travels a separate channel. That is why a context value has to be wrapped in useMemo — exactly the point of our theme switching variant, where deleting the useMemo left every behaviour test green and only the reference-stability test red.
“Does children break memo?” — yes. children is a prop too, and JSX produces a new element object every time.