记忆化 React 组件

2025-06-10

记忆化 React 组件

好吧,首先什么是 Memoization?

在计算中,记忆是一种优化技术,主要用于通过存储昂贵的函数调用的结果并在再次出现相同输入时返回缓存的结果来加速计算机程序。

换句话说,记忆化是一种降低函数时间成本以换取空间成本的方法;也就是说,记忆化函数针对速度进行了优化,以换取更高的计算机内存空间利用率。

如下图所示,一个名为 sum 的函数被多次调用。即使使用相同的参数调用该函数,1,2它也必须重新计算结果。

说明函数被多次调用的图表

那么,如果我们把已经计算好的结果存储在内存中,与每次调用时传递的参数相对应,岂不是很好?这样,如果我们观察到传递的参数的结果已经计算出来,就可以直接从内存中返回。

黑人思考表情包

看一下下面的函数调用图,您可以看到,当我们memoSum(1,2)使用相同的参数第二次调用时,结果直接从内存返回1,2

图表显示记忆函数被多次调用

如果我们考虑的函数不是 CPU 密集型的,那么没有记忆的函数是很好的,但是,如果你考虑一个被频繁调用的纯函数,并且需要相当长的时间才能返回结果,那么最好记忆该函数,这样就可以使用已经计算的结果,而不必对相同的参数进行一次又一次的计算。

永远记住,只有纯函数才能被记忆。如果你不知道如何定义纯函数,可以参考以下文章,ysael pepin它解释了函数式编程的一些最基本概念:https://dev.to/ysael/ functional-programming-basics-part-1-pure-function-e55

我们如何记忆给定的纯函数?

嗯,有很多可用的库已经实现了记忆并为此提供了不同的 API。

Lodashmemoize是提供解决此问题的函数的 JavaScript 库之一。

const lodash = require('lodash'); const add = function(a, b){return a + b}; const memoizedAdd = lodash.memoize(add); console.log('1 + 1', memoizedAdd(1,1)); // This will return the memoized result console.log('1 + 1', memoizedAdd(1,1));

但是记忆化与 React 组件有什么关系?

我们已经知道,React 组件就像另一个返回一堆 HTML 标签的 JavaScript 函数,我们称之为JSX,传递给这个函数的参数称为Props

图片包含一个表情包,上面写着“如果它走起来像鸭子,叫起来也像鸭子,那么它一定是鸭子”

是的,你的猜测是正确的,我们绝对可以记住一个 React 组件。

使用 React.memo 来记忆 React 组件

const MemoizedComponent = React.memo(function MyComponent(props) {
  /* render using props */
});

Enter fullscreen mode Exit fullscreen mode

React.memo 是一个高阶组件。它的功能与React.PureComponent类似,但属于函数式组件。

如果你的函数组件在给定相同 props 的情况下渲染相同的结果,你可以将其包装在一个调用中,React.memo()以便在某些情况下通过记忆结果来提高渲染速度。这意味着 React 将跳过组件的渲染过程,并且不会执行虚拟 DOM 差异检查,它只会重用上次渲染的结果。

export function PassengerDetails({ passengerName, departureDate }) {
  return (
    <div>
      <div>Passenger: {passengerName}</div>
      <div>Departure: {departureDate}</div>
    </div>
  );
}

export const MemoPassengerDetails = React.memo(PassengerDetails);

Enter fullscreen mode Exit fullscreen mode

默认情况下,它只会浅层比较 props 对象中的复杂对象。

如果您想要控制比较,您还可以提供自定义比较函数作为第二个参数。


export function PassengerDetails({ passengerName, departureDate }) {
  return (
    <div>
      <div>Passenger: {passengerName}</div>
      <div>Departure: {departureDate}</div>
    </div>
  );
}


function areEqual(prevProps, nextProps) {
  /*
  return true if passing nextProps to render would return
  the same result as passing prevProps to render,
  otherwise return false
  */
}

export default React.memo(PassengerDetails, areEqual);

Enter fullscreen mode Exit fullscreen mode

限制

  1. 为了能够记忆,该函数必须是纯函数
  2. 当空间比计算时间更重要时,您可能不需要记住您的函数。
  3. 当你的函数执行频率较低时,记忆该函数并没有太多好处。

要记住的事情

  1. 不要memoize使用 Lodash 的 React.memo 来记忆 React 组件,因为后者对与 React 组件的配合使用进行了更优化。
  2. React.memo 仅对 props 进行浅层比较,如果要深度比较 props,那么最好将自己的比较函数作为React.memo函数中的第二个参数传递。
  3. 不要混淆React.memouseMemo您可以在以下文章中了解useMemo哪些内容解释得很好- https://dev.to/spukas/react-usememo-for-optimisation-5gnaLinas Spukas

如果您发现该文章内容丰富,请不要忘记关注。

祝你编码愉快:)

有兴趣看看我的其他文章吗?
学习一些 Web 无障碍方面的最佳实践,它们将帮助你的 Web 内容或 Web 应用程序触达更广泛的受众。

了解代码分割是如何成为你所忽略的事情的。

了解可选链和空值合并如何使您的代码看起来更干净、更易读。

鏂囩珷鏉ユ簮锛�https://dev.to/redraushan/memoizing-react-components-2km7
PREV
使用 refine 和 Strapi 在 15 分钟内创建反馈管理面板
NEXT
开发人员招聘:如何阅读招聘广告