Skip to content
Go back

react memo

编辑网页

Table of contents

Open Table of contents

react memo 优化了什么,react 不是有 diff 算法吗

确实,React 有强大的 diff 算法(即 Virtual DOM 的比较和更新机制),但这并不意味着每次更新时都能做到“只更新真正需要的组件”。而 React.memo 就是在 diff 之前 提供了更早的“优化机会”。


React.memo 是一个高阶组件,用来 跳过函数组件的重新渲染前提是 props 没有变化


那 React 的 diff 算法做了什么?

React 的 diff 算法会:

但是:

如果父组件重新渲染,子组件默认也会跟着重新执行函数组件体,即使 props 没变。

这就是性能浪费的来源,特别是:


React.memo 优化了什么?

它优化的是**“是否要重新执行函数组件”**这个问题。

所以 React.memo组件级别的浅比较缓存机制


举个例子:

const Child = React.memo(({ name }) => {
  console.log("Child render");
  return <div>Hello {name}</div>;
});

function Parent() {
  const [count, setCount] = React.useState(0);
  return (
    <>
      <button onClick={() => setCount(c => c + 1)}>+1</button>
      <Child name="Jee" />
    </>
  );
}

每次点击按钮时,父组件重新渲染了,但 Child 的 props 没变:


补充疑问

父组件更新 → 子组件函数重新执行,不是会有 diff 决定复用吗,怎么还需要 memo

你的疑问非常关键,咱们来拆解这个过程,澄清误区 👇

React 的 diff 确实会决定 DOM 是否复用

React 的 diff 算法只在 Virtual DOM 层判断:

“这个 DOM 节点要不要更新?”

所以:

这意味着:

function Child({ name }) {
  console.log("Child render");
  return <div>{name}</div>;
}

如果你没用 React.memo,只要父组件更新,Child 函数就会重新执行一遍,哪怕 name 没变,最后 Virtual DOM 是一样的,React 仍然花了时间构造它并 diff 一次 —— 这就是性能浪费。


React.memo 的作用就是:连函数都别跑,直接复用旧结果

来看两种流程对比:

普通组件(没有 memo

  1. 父组件更新;
  2. 子组件函数重新执行,生成新的 Virtual DOM;
  3. React 比较旧的 Virtual DOM 和新的;
  4. 发现一样,不更新 DOM —— 但函数已经跑了!

使用 React.memo

  1. 父组件更新;
  2. React 比较 Childprops 是否有变化(浅比较);
  3. 如果 props 没变,跳过组件函数执行,也不生成新的 Virtual DOM,也不触发 diff。

一个形象比喻:

React 的 diff 是“你写好文章后,编辑器比对前后差别,决定哪些句子要重写”;

React.memo 是“看你用的资料有没有变,没变就直接复用上次写好的文章,连写都不写了”。


什么时候该用 React.memo

适合这些情况:


注意:不是越多用 React.memo 越好


编辑网页
Share this post on:

Previous Post
cdn使用初体验