【React】有关React中的记忆化(useCallback / useMemo / React.memo)【React】关于React中的记忆化(useCallback / useMemo / React.memo)

嗨,大家好,我是@ちーず。
今天是Advent Calender第五天,我们的主题是关于React中的记忆化!

什么是记忆化(メモ化)?

这是一种用于程序加速的优化技术之一,它通过保存子程序调用的结果以便以后再利用,以防止每次调用子程序(函数)时的重复计算。

记忆化函数会将先前调用时的结果与参数一起存储起来,以便在以后使用相同参数调用时,不需要重新计算,而是返回存储的结果。

参考:记忆化 – 维基百科

换句话说,把计算结果进行缓存并重新利用,这就是所谓的记忆化。

为什么需要进行备忘录记忆化?

在React中,组件会在以下时机进行重新渲染。

state / props が更新された時

親コンポーネントが再レンダリングされた時

当重新渲染一个组件时,
该组件内定义的函数和变量也会被重新生成,
即使值没有改变, 也会被重新计算。

如果在React中掉以轻心,那么意外的重新计算可能会增加,这可能会影响网站的性能,因此记忆化的重要性就很高。

进行记忆化时的注意事项

在处理轻量级任务时进行记忆化会增加访问缓存的开销。
此外,记忆化的必要性也因应用程序而异。

因此,我认为不应该将所有事情都记忆化,而是在执行后确认性能是否真正改善,然后再进行记忆化,这样可以更好地提高性能。

顺便提一下,我之前对什么事情都过于依赖记笔记了…我要反省一下。

通过使用 React.memo 进行组件的记忆化

React.memo是一个将组件进行记忆化的高阶组件(HOC)。当props的值没有变化时,它可以阻止组件重新渲染。

高阶组件(HOC)是一个函数,它接收一个组件作为参数,并返回一个新的组件。

如何写

// 第一引数: 関数Component

export const heavyComponent = React.memo(() => (
  // とても思い処理
  <p>子Componentです</p>
));

什么情况下会使用这个?

成本高昂的渲染组件

如果组件本身有繁重的处理任务,通过进行记忆化可以避免进行渲染。

某些组件可能会频繁重新渲染。

如果父组件的变化经常发生,子组件每次都会进行不必要的重新渲染,因此建议使用React.memo来进行记忆化。

如果Component的渲染频繁地依赖于父组件的处理,那么可能是组件设计本身存在问题。

在这种情况下,推荐的做法不是简单地进行记忆化,而是重新审视设计后再进行记忆化。

使用useMemo对值进行记忆化处理

useMemo是一个钩子,可以用于对执行结果或值进行记忆化。

写作方式

// 第一引数: コールバック関数
// 第二引数: 依存配列 - この値が変更された時のみ再計算

useMemo(() => function(), [deps])

在什么时候使用?

如果要进行非常耗费成本的计算

阐明“非常昂贵”的定义很困难,但是阅读下面的文章后,我觉得在进行大约100次循环的数组时使用useMemo可能没有意义。

参考: 未经过备忘录记录的情况下

    • 500回以上のループ処理並の複雑さの処理

 

    何度も再レンダーされる可能性がある

我觉得这可能是一个可以派上用场的时机!

使用`useCallback`来对函数进行记忆化。

useCallback是一个返回记忆化callback函数的hooks。

写作方式

// 第一引数: コールバック関数
// 第二引数: 依存配列

const func = useCallback(() => {
  // callback関数
}, [deps]);

在什么时候使用?

返回一个函数的自定义钩子

自定义钩子是为了定义具有高重用性的钩子,以便在组件被调用时,用户端无需考虑该函数是否会被重新生成而进行设计。因此,如果自定义钩子返回函数,则基本上建议进行记忆化处理。

由于作者对下面这篇文章深受感动,所以对于想要了解更多的人,强烈推荐阅读!

请将以下内容以中文进行释义,只需要提供一种选项:

参考如下

如果将函数传递给记忆化的组件

以下是对React.memo的复习,当props的值相同时,不会进行重新渲染。

然而,如果直接将该函数传递给被缓存的子组件,那当父组件重新渲染时,函数会被再次生成,因此无法判断为相同的值,导致重新渲染。

为了保持函数的一致性,请使用useCallback将其包裹起来!


以上是关于React中记忆化的内容!!我想有一天尝试进行记忆化性能改进实验呢~

广告
将在 10 秒后关闭
bannerAds