🚀 React.memo 深入解析:让函数组件“记住”渲染结果

在 React 开发中,性能优化一直是前端工程师绕不开的话题。而在函数组件中,一个非常实用的性能优化工具就是 —— React.memo
本文将带你从原理到实践,全面理解它的工作机制、使用场景,以及一些常见的坑点。


一、什么是 React.memo?

React.memo 是一个 高阶组件(Higher Order Component,HOC),用于 缓存函数组件的渲染结果,从而避免不必要的重新渲染。

简单来说:

如果一个组件在相同的 props 下渲染结果是一样的,那么 React.memo 会让这个组件“记住”上一次的渲染结果,直接复用,而不重新执行渲染逻辑。

✅ 基本语法

"use client";

import React, { useState } from "react";

const MyComponent = React.memo(function MyComponent(props: { value: string }) {
  console.log("组件渲染了!");
  return <div>{props.value}</div>;
});

// ✅ 页面组件
export default function Test() {
  return (
    <MyComponent value="Hello, World!" />
  );
}

在这里插入图片描述

使用后,只要 props.value 没有变化,组件就不会重新渲染。


二、工作原理

默认情况下,React.memo 会对组件的 props 进行浅层比较(shallow compare)

也就是说:

  • 如果 props 是 基本类型(如 string、number、boolean),值相同则认为没变;
  • 如果 props 是 对象、数组或函数,即使内容相同,只要引用不同,也会被认为“发生了变化”。

举个例子👇:

"use client";

import React, { useState } from "react";

const Parent = () => {
  const [count, setCount] = useState(0);
  const obj = { name: "React" };

  return (
    <>
      <button onClick={() => setCount(count + 1)}>+1</button>
      <Child data={obj} />
    </>
  );
};

const Child = React.memo(({ data }: { data: { name: string } }) => {
  console.log("Child 重新渲染了!");
  return <div>{data.name}</div>;
});

// ✅ 页面组件
export default function Test() {
  return (
    <Parent />
  );
}

在这里插入图片描述

你可能会以为点击按钮不会让 Child 重新渲染,但实际上 每次渲染 Parent 时都会创建新的 obj 对象引用,因此 Child 会重复渲染。


三、解决方案:自定义比较函数

React.memo 允许你传入一个自定义比较函数,用来自定义 props 的比较逻辑。

"use client";

import React, { useState } from "react";

const Parent = () => {
  const [count, setCount] = useState(0);
  const obj = { name: "React" };

  return (
    <>
      <button onClick={() => {
        console.log("按钮点击,新的计数:", count + 1);
        setCount(count + 1);
      }}>
        +1
      </button>
      <Child data={obj} />
    </>
  );
};

const Child = React.memo(
  ({ data }: { data: { name: string } }) => {
    console.log("Child 渲染");
    return <div>{data.name}</div>;
  },
  (prevProps, nextProps) => {
    return prevProps.data.name === nextProps.data.name;
  }
);

// ✅ 页面组件
export default function Test() {
  return (
    <Parent />
  );
}

在这里插入图片描述

通过这个函数,你可以灵活地控制什么时候跳过渲染。


四、React.memo vs useMemo vs useCallback

很多开发者初学时会混淆这三个 API,我们来简单区分一下👇

API 用途 使用位置 对比机制
React.memo 缓存组件渲染结果 包裹组件外部 比较 props
useMemo 缓存函数执行结果 组件内部 比较依赖项
useCallback 缓存函数定义 组件内部 比较依赖项

一句话总结:

React.memo 优化的是 组件级别的渲染,而 useMemo 和 useCallback 优化的是 组件内部逻辑


五、适用场景与注意事项

✅ 适用场景

  • 子组件渲染成本较高(如复杂 UI 或数据计算)
  • 父组件频繁更新,但子组件的 props 基本不变
  • 多个纯展示型组件重复渲染

⚠️ 不推荐滥用

  • 如果组件渲染成本很低,使用 React.memo 反而会引入额外的比较开销;
  • 不要指望它“自动优化”一切 —— 需要你明确知道为什么组件会重新渲染;
  • 注意避免对象/函数引用变化引起的“假变化”,可配合 useCallbackuseMemo

六、总结

特点 说明
本质 缓存函数组件渲染结果
比较方式 默认浅比较 props,可自定义比较函数
使用场景 避免不必要的子组件渲染
搭配使用 常与 useCallback/useMemo 一起使用
注意事项 谨慎使用,避免过度优化

🎯 一句话总结

React.memo 就像函数组件的“记忆缓存”,让 React 在渲染时更聪明、更高效。但记住——优化之前,请先衡量是否真的需要!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐