您的位置:首页 > Web前端 > React

react usememo_看看React useMemo Hook

2020-08-13 11:47 681 查看

react usememo

You may have seen, released along with React Hooks, a strange hook called

useMemo
. What could this strange, 👽alien👽 hook mean and what is it used for? Most importantly, how can it help you and why do you need to know about it?

您可能已经看到,与React Hooks一起发布了一个名为

useMemo
的奇怪钩子。 这个奇怪的“ alien”钩子可能意味着什么,它的作用是什么? 最重要的是,它如何为您提供帮助?为什么您需要了解它?

First, a little brush up on JavaScript equality.

首先,稍微回顾一下JavaScript的相等性。

参照平等 (Referential Equality)

You may remember how Javascript compares objects 🥴. There are some tricky results when we run equality comparisons:

您可能还记得Javascript如何比较对象🥴。 当我们进行相等比较时,会有一些棘手的结果:

{} === {} // false

const z = {}
z === z // true

React uses

Object.is
to compare components, but that gives very similar results to using
===
. So, when React checks for any changes in a component, it may find a “change” that we wouldn’t really consider a change.

React使用

Object.is
比较组件,但是给出的结果与
===
非常相似。 因此,当React检查组件中的任何更改时,它可能会发现一个我们不会真正考虑的更改。

() => {} === () => {} // false
[] === [] // false

This comparison check will cause some React re-rendering we didn’t intend or expect. If that re-rendering is some expensive operation, that can hurt performance. If one part re-renders, it re-render the entire component tree. Thus, React released the memo idea to fix this.

此比较检查将导致某些我们未曾计划或期望的React重新渲染。 如果重新渲染是一项昂贵的操作,则可能会损害性能。 如果一部分重新渲染,则它将重新渲染整个组件树。 因此,React发布了备忘录的想法来解决此问题。

记忆化 (Memoization)

You may have heard this fancy word, memoization. Memoization is basically an optimization technique which passes a complex function to be memoized or remembered. In memoization, the result is remembered, when the same exact parameters are passed-in subsequently. Kind of like memorization. If we have a function compute 1 + 1, it will return 2. But if it uses memoization, the next time we run 1’s through the function it won’t add them up, it will just remember the answer is 2 without executing the adding function.

您可能已经听过这个花哨的单词, 回忆 。 记忆基本上是一种优化技术 ,它传递了要记忆或记忆的复杂功能。 在记忆中,当随后传递相同的确切参数时,会记住结果。 有点像背诵 。 如果我们有一个计算1 + 1的函数,它将返回2。但是如果它使用备忘录,则下次我们通过该函数运行1时,它不会将它们加起来,它只会记住答案是2,而无需执行加法运算功能。

In React, memoization optimizes our components, avoiding complex re-rendering when it isn’t intended. Here is a great article on using React.memo to optimize your application. React.memo acts like a pure component, wrapping your component and the linked article does a great job explaining it. However, useMemo is a bit different in usage.

在React中,备忘录可以优化我们的组件,避免在不需要时进行复杂的重新渲染。 是一篇关于使用React.memo优化应用程序的精彩文章。 React.memo就像一个纯组件一样,包装您的组件,链接的文章在解释它方面做得很好。 但是,useMemo的用法有些不同。

From the official React documentation, useMemo’s signature looks like this:

从官方的React文档中 ,useMemo的签名如下所示:

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

As you can see,

useMemo
takes in a function and a list of dependencies (the array
[a, b]
). If you are familiar with useEffect, then you have probably seen the dependencies idea. They act similar to arguments in a function. The dependencies list are the elements useMemo watches: if there are no changes the function result will stay the same, otherwise it will re-run the function. If they don’t change, it doesn’t matter if our entire component re-renders, the function won’t re-run but instead return the stored result. This can be optimal if the wrapped function is large and expensive. That is the primary use for useMemo.

如您所见,

useMemo
接受一个函数和一个依赖关系列表(数组
[a, b]
)。 如果您熟悉useEffect ,那么您可能已经看到了依赖项的想法。 它们的行为类似于函数中的参数。 依赖关系列表是useMemo监视的元素:如果没有更改,函数结果将保持不变,否则它将重新运行该函数。 如果它们没有变化,那么整个组件是否重新渲染都没有关系,该函数将不会重新运行,而是返回存储的结果。 如果包装功能很大且很昂贵,这可能是最佳的。 那是useMemo的主要用途。

useMemo示例 (useMemo Example)

const List = useMemo(
() =>
listOfItems.map(item => ({
...item,
itemProp1: expensiveFunction(props.first),
itemProp2: anotherPriceyFunction(props.second)
})),
[listOfItems]
)

In the above example, the useMemo function would run on the first render. It would block the thread until the expensive functions complete, as

useMemo
runs in the render. Initially, this won’t look as clean as useEffect, since useEffect can render a loading spinner until the expensive functions finish and the effects fire off. However, the expensive functions would never fire off again if
listOfItems
never changed and we would still get the return value from them. It would make these expensive functions seem instantaneous. This is ideal of you have an expensive, synchronous function or two.

在上面的示例中,useMemo函数将在第一个渲染器上运行。 它将阻塞线程,直到昂贵的功能完成为止,因为

useMemo
在渲染
useMemo
运行。 最初,它看起来不如useEffect干净,因为useEffect可以渲染加载微调器,直到昂贵的函数完成并且效果消失为止。 但是,如果
listOfItems
从未更改,则昂贵的函数将永远不会再次
listOfItems
,我们仍然会从中获取返回值。 这将使这些昂贵的功能看起来是瞬间的。 这是您拥有一两个昂贵的同步功能的理想选择。

防止重新渲染 (Prevent Re-Rendering)

If you’re familiar with React’s class-component lifecycle hook, shouldComponentUpdate,

useMemo
has a similar usage in preventing unnecessary re-renders. Let’s say we have this instance:

如果您熟悉React的类组件生命周期挂钩, shouldComponentUpdate ,

useMemo
在防止不必要的重新渲染方面也有类似用法。 假设我们有这个实例:

function BabyGator({fish, insects}) { // because what else do baby gators eat?
const dinner = {fish, insects};
useEffect(() => {
eatFunction(dinner);
}, [fish, insects])
}

function MamaGator() {
return <BabyGator fish='small edible fish' insects={15}>
}

This works perfectly well. Our

useEffect
hook watches the fish and insects props being passed-in (he is hungry). However, this only works with primitive values. That’s the key.

这工作得很好。 我们的

useEffect
挂钩
useEffect
被传入的鱼和昆虫道具(他饿了)。 但是,这仅适用于原始值。 那是关键。

Remember back to talking about Referential Equality?

[] === [] // false
. That’s exactly what memoizing hooks like
useMemo
and
useCallback
are made for. If our insects prop is an array, we can put it in the
useMemo
hook and it will reference it, after a render, as equal. If a function or another non-primitive value is in the
useEffect
dependency, it will recreate a new array, because of closure, and find it unequal.

记得回到谈论参照平等吗?

[] === [] // false
。 这正是诸如
useMemo
useCallback
类的
useMemo
挂钩的
useMemo
。 如果我们的昆虫道具是一个数组,我们可以将其放在
useMemo
钩子中,并在渲染之后将其引用为相等。 如果一个函数或其他非基本值是
useEffect
依赖,它会重建一个新的数组,因为封闭 ,并发现它是不平等的。

Obviously here, we don’t need

useMemo
, if all we are doing is memoizing an array. But if there was an expensive function to calculate that array,
useMemo
would be useful!

显然,在这里,如果我们要做的只是存储数组,则不需要

useMemo
。 但是,如果有一个昂贵的函数来计算该数组,则
useMemo
将很有用!

何时不使用备忘录 (When Not to useMemo)

The

useCallback
hook is similar to
useMemo
, but it returns a memoized function, while
useMemo
has a function that returns a value. If our dependencies array is empty, there is no possibility of memoization and it will compute a new value on every render. You might as well implement the
useRef
hook at that point. The advantage
useMemo
offers over
useRef
is a re-memoizing if the dependencies change.

useCallback
挂钩与
useMemo
相似,但是它返回一个已记忆的函数 ,而
useMemo
具有一个返回值的函数。 如果我们的依赖项数组为空,则不可能进行记忆,它将在每个渲染器上计算一个新值。 您最好在
useRef
实现
useRef
挂钩。 如果依赖项发生更改,
useMemo
提供的优于
useRef
的优势是重新存储。

When looking to implement

useMemo
always ask, “is this really an expensive function?” Expensive means it is sucking up a lot of resources (like memory). If you are defining a ton of variables in a function at render, it might make sense to memoize with
useMemo
.

在寻求实现

useMemo
总是会问:“这真的是一项昂贵的功能吗?” 昂贵意味着它正在消耗大量资源(例如内存)。 如果要在render函数中定义大量变量,则使用
useMemo
可能
useMemo

You won’t want to have

useMemo
fire off any side effects or any asynchronous calls. Both of those would make more sense to be contained within
useEffect
.

您不会希望

useMemo
触发任何副作用或任何异步调用。 将两者包含在
useEffect

When looking to implement

useMemo
, write the code first then revisit it to see if you can optimize it. Don’t start with
useMemo
. Too many people implement it quickly and it can make performance worse in a small application.

当寻求实现

useMemo
,请首先编写代码,然后重新访问它以查看是否可以对其进行优化。 不要以
useMemo
。 太多的人很快实现了它,并且在小型应用程序中可能会使性能变差。

参考 (Reference)

As always, it’s ideal to visit the official docs. From the docs, you’ll see that the following is also recommended:

与往常一样,最好访问官方文档 。 从文档中,您还将看到以下建议:

We recommend using the exhaustive-deps rule as part of our eslint-plugin-react-hooks package. It warns when dependencies are specified incorrectly and suggests a fix.

我们建议在我们的eslint-plugin-react-hooks程序包中使用详尽的下降规则。 当错误指定依赖项时,它会发出警告,并提出修复建议。

翻译自: https://www.digitalocean.com/community/tutorials/react-usememo

react usememo

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: