介绍
随着 React 16.8 的发布,您现在可以在 React 应用程序中使用许多有用的钩子。16.8 中引入的内置 Hook 之一是useMemo
. 这个钩子有可能提高你的应用程序的性能。
本文将探讨在 React 中重新渲染是如何工作的,为什么这是 React 应用程序的一个重要考虑因素,以及useMemo
钩子如何利用它来提高应用程序的性能。您还将了解何时useMemo
会导致性能问题。
先决条件
要完成本教程,您需要:
- 在开始本教程之前对 React 有一个基本的了解。您可以通过阅读如何在 React.js系列中编码来了解有关 React 的更多信息。
引用相等和昂贵的操作
有两个问题useMemo
需要解决:
- 指称平等
- 计算成本高的操作
在组件的生命周期中,React 会在进行更新时重新渲染组件。当 React 检查组件中的任何更改时,由于 JavaScript 处理相等性和浅层比较的方式,它可能会检测到意外或意外的更改。React 应用程序中的这种更改将导致它不必要地重新渲染。
此外,如果重新渲染是一项昂贵的操作,例如 long for loop
,则可能会损害性能。昂贵的操作在时间、内存或处理方面都可能是昂贵的。除了潜在的技术问题外,这可能会导致用户体验不佳。
如果一个部分重新渲染,它会重新渲染整个组件树。
因此,React 发布了memo
解决这个问题的想法。
理解记忆
Memoization是一种优化技术,它传递一个复杂的函数来进行记忆。在记忆中,当随后传入相同的参数时,结果会被“记住”。
如果我们有一个函数计算1 + 1
,它将返回2
。但是如果它使用记忆化,下次我们1
通过函数运行‘s 时,它不会将它们相加;它只会记住答案是2
不执行添加功能。
从官方React 文档中,useMemo
的签名如下所示:
const memoizedValue = React.useMemo(() => computeExpensiveValue(a, b), [a, b]);
useMemo
接受一个函数和一个依赖项数组。
依赖项的作用类似于函数中的参数。依赖项的列表是元素useMemo
手表:如果没有变化,函数结果将保持不变。否则,它将重新运行该函数。如果它们没有改变,我们的整个组件是否重新渲染都没有关系,函数不会重新运行,而是返回存储的结果。如果包装的函数很大而且很昂贵,这可能是最佳的。这是 的主要用途useMemo
。
创建useMemo
示例
下面是一个抽象示例,useMemo
用于使用两个计算成本高的函数的项目数组:
const List = React.useMemo(() =>
listOfItems.map(item => ({
...item,
itemProp1: expensiveFunction(props.first),
itemProp2: anotherPriceyFunction(props.second)
})), [listOfItems]
)
在上面的示例中,该useMemo
函数将在第一次渲染时运行。它会阻塞线程,直到昂贵的函数完成,就像useMemo
在第一次渲染中运行一样。
最初,这看起来不像 干净useEffect
,因为它useEffect
可以渲染加载微调器,直到昂贵的函数完成并触发效果。
然而,在随后的渲染中,只要listOfItems
不改变,昂贵的函数就不需要再次运行。useMemo
会“记住”每个函数的返回值。
它会使这些昂贵的函数看起来是即时渲染的。如果您有一两个昂贵的同步功能,这是理想的选择。
何时使用 useMemo
先写代码,再回看,看能不能优化。如果useMemo
在应用程序中实施过于频繁,可能会损害性能。
在寻求实施时useMemo
,您可以使用分析工具检查以识别代价高昂的性能问题。昂贵意味着它正在使用大量资源(如内存)。如果您在渲染时在函数中定义大量变量,则使用useMemo
.
为工作使用正确的钩子
除此之外useMemo
,还有useCallback
、useRef
、 和useEffect
。
该useCallback
挂钩类似useMemo
,但它返回一个memoized功能,同时useMemo
有一个函数返回一个值。
如果未提供您的依赖项数组,则不可能进行记忆,并且它会在每次渲染时计算一个新值。你可以useRef
在那种情况下使用钩子。如果依赖关系发生变化useMemo
,useRef
则提供的优势是重新记忆。
您不会希望useMemo
触发任何副作用或任何异步调用。在这些情况下,您应该使用useEffect
.
结论
本文探讨了useMemo
钩子以及何时适合在 React 应用程序中使用它。
useMemo
可以通过“记住”昂贵的函数并防止每次应用程序发生更改时重新渲染来帮助应用程序的性能。
虽然使用这个钩子可以提高性能,但如果你过度使用它,它也会降低你的应用程序的速度。使用钩子越多,应用程序分配的内存就越多。
要了解有关 React 最佳实践的更多信息,请关注DigitalOcean 上完整的How To Code in React.js系列。