react usememo
Learn how to optimise your React app performance by using the useMemo() and useCallback() hooks correctly and also learn when to use the React.memo function.
了解如何通过正确使用 useMemo() 和 useCallback() 挂钩 来优化React应用性能, 并了解何时使用 React.memo 函数。
Did you know that React offers a function called React.memo to optimise performance? And also, did you know that React offers hooks called useCallback() and useMemo() which again can optimise the app performance?. Are you confused about when to use which technique? I will explain the most common use-cases of these techniques with a simple example so that you can learn and ship highly performant react applications in the future.
您是否知道React提供了一个称为React.memo的函数来优化性能? 而且,您是否知道React提供了称为useCallback()和useMemo()的钩子,它们又可以优化应用程序性能? 您对何时使用哪种技术感到困惑吗? 我将通过一个简单的示例来解释这些技术的最常见用例,以便您将来可以学习和发布高性能的React应用程序。
React.memo (React.memo)
React.memo is a Higher Order Component. You can wrap your component with React.memo(<Component />) for a performance boost by memoising the result of the component.
React.memo是一个高阶组件 。 您可以使用React.memo(<Component />)包装组件,以通过记录组件的结果来提高性能。
Here is a simple example.
这是一个简单的例子。
![Image for post](https://miro.medium.com/freeze/max/9999/1*W3jO-WuElBXNknd8Qe95Tg.gif)
If you look closely, every single time we click the Up button to increment the local state, our child component re-renders, which is unnecessary as the prop passed down to the child component never changes.
如果仔细观察,每次我们单击“向上”按钮以增加本地状态时,子组件都会重新渲染,这是不必要的,因为传递给子组件的prop永远不会改变。
We can use the React.memo function to memoise the child component to avoid this un-necessary re-render. React.memo is a HOC, which will only re-render the component if the props change.
我们可以使用React.memo函数来记住子组件,以避免不必要的重新渲染。 React.memo是一个HOC,仅当props更改时才会重新渲染组件。
![Image for post](https://miro.medium.com/freeze/max/9999/1*bpe5qfiYWqizLeTMKOBZ3g.gif)
useCallback()挂钩 (useCallback() Hook)
The useCallback() hook returns a memoized callback.
useCallback()挂钩返回备注的回调。
To learn how to use this hook, we first need to break the memoized component we created above.
要学习如何使用此挂钩,我们首先需要破坏上面创建的备注组件。
![Image for post](https://miro.medium.com/freeze/max/9999/1*jPjrMZG-12tz2_BfrLTkdQ.gif)
I’ve passed the incrementChildState function as a prop to the child component.
我已经传递了crementChildState函数作为对子组件的支持。
Let’s now look at how it works.
现在让我们看看它是如何工作的。
![Image for post](https://miro.medium.com/freeze/max/9999/1*ICsuj-HDN7mosJj7WpCwFQ.gif)
So we are back to square one. Our React.memo is not working anymore, and the child component re-renders again if even if we are only incrementing the state in the parent component.
所以我们回到正题。 我们的React.memo不再工作,即使我们只是在父组件中增加状态,子组件也会重新渲染。
useCallback() hook to the rescue :)
useCallback()可以进行救援:)
But before we jump in, we need to understand the concept of referential equality in JavaScript.
但是在开始之前,我们需要了解JavaScript中的引用相等的概念。
Here is a super-informative article written by Dmitri Pavlutin which clearly explains the concept of referential equality.
这是Dmitri Pavlutin撰写的超级信息文章 这清楚地解释了引用相等的概念。
So basically, defining referential equality in our context is on every single render we are creating an entirely brand new incrementChildState function.
因此,基本上,在我们的上下文中定义参照相等性是在每个渲染上,我们创建一个全新的增量儿童状态函数。
So our child component which is wrapped inside a React.memo HOC does a referential equality check and see’s that the setNumber prop changes on every render cycle, hence the memoized function re-render.
因此,包装在React.memo HOC内的子组件进行了引用相等性检查,发现setNumber属性在每个渲染周期都发生了变化,因此记忆化的函数会重新渲染。
The useCallback() hook accepts two arguments and then returns a new function. The first argument is the function that we need to memoize and the second argument is a dependency array which is similar to the useEffect() hook’s dependency array, we never want the function to change, so we pass in an empty dependency array.
useCallback()挂钩接受两个参数,然后返回一个新函数。 第一个参数是我们需要记住的函数,第二个参数是一个依赖数组,它类似于useEffect()钩子的依赖数组,我们从不希望函数更改,因此我们传入一个空的依赖数组。
With this change, the memoizedCallback function will stay the same referentially.
进行此更改后, memoizedCallback函数将保持引用不变。
![Image for post](https://miro.medium.com/freeze/max/9999/1*sZRZfetLdjr62ZwvewEnpw.gif)
useMemo()挂钩 (useMemo() Hook)
useMemo
will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render.
useMemo
当一个依赖已经改变,只会重新计算memoized值。 此优化有助于避免对每个渲染进行昂贵的计算。
Let’s take an example where we compute the largest value in an array and render it.
让我们举一个例子,我们计算数组中的最大值并渲染它。
![Image for post](https://miro.medium.com/freeze/max/9999/1*2RMOOAWfS-03sAp0Mpw_GQ.gif)
Every time we try to increment the child component state, we are computing the largest number in the array which is really inefficient and expensive computation.
每次我们尝试增加子组件状态时,我们都在计算数组中的最大数,这实际上是低效且昂贵的计算。
useMemo() hook will accept a function as an argument, and cache the function until the arguments the function depends on actually changes.
useMemo()挂钩将接受一个函数作为参数,并缓存该函数,直到该函数所依赖的参数实际更改为止。
![Image for post](https://miro.medium.com/freeze/max/9999/1*LnqWmVg90hbBwMUY1KSQhw.gif)
恭喜⚡ (Congratulations ⚡)
If you manage to reach this far, then I hope you have learned something about useCallback(), useMemo and React.memo.
如果您设法做到这一点,那么我希望您对useCallback(),useMemo和React.memo有所了解。
My twitter handle is @kabeerajin
我的推特句柄是@kabeerajin
I learned all these cool concepts from a YouTube video. Here is a link to a super informative YouTube video by Chaim.
我从YouTube视频中学到了所有这些很棒的概念。 这是Chaim提供的内容丰富的YouTube视频的链接 。
Thank you!
谢谢!
react usememo