preface

Just finished writing an understanding of useMemo, I’m going to write about my understanding of useCallBack

The difference between useMemo and useCallBack

In simple terms, useMemo specifically caches the value returned by this method in order to eliminate unnecessary duplication of rendered methods. To avoid repeated calculation of this method, the code is as follows:

const foo = useMemo(() => {
    // ... complex calc
    // return calc
}, [])
Copy the code

UseCallBack is also designed to eliminate unnecessary duplication of renderings, but caches the entire function. The code is similar to useMemo:

const foo = useCallBack(() => {
    // ... todo
}, [])
Copy the code

Usage scenarios

Consider the following code:

import React, { useState } from 'react'; function Comp() { const [dataA, setDataA] = useState(0); const [dataB, setDataB] = useState(0); const onClickA = () => { setDataA(o => o + 1); }; const onClickB = () => { setDataB(o => o + 1); } return <div> <Cheap onClick={onClickA}> 标 签 : Expensive {dataB}</Expensive> </div> }Copy the code

Analysis is as follows:

  • The Comp component defines two sub-components, Cheap and Expensive, which are not displayed. The Cheap component is a simple component, and the Expensive component is a fairly Expensive component, and both have onClick events.
  • When the component Cheap triggers the onClick event, the state update causes the entire Comp component to be rerendered. Then the component Expensive was rendered. Nothing was done, the properties were not changed, even the onClick function was not changed, but the component was rendered again after the global State changed, which resulted in unnecessary rendering.
  • To avoid performance defects caused by repeated rendering, you can see that the component has not changed at all, whether it is a property or a click functionmemoTo wrap the entire component:
Function Expensive({onClick, name}) {console.log('Expensive render '); return <div onClick={onClick}>{name}</div> } const MemoExpensive = memo(Expensive) ... Return (<div> <Cheap onClick={onClickA}> 标 签 : Expensive ${dataB}`} /> </div> )Copy the code
  • The memo function is similar to the react Class componentpureComponentOr is itshouldComponentUpdateThe main function is to compare the consistency of all properties of the component. So this is an important point of performance tuning.
  • But memo compares attributes, so how do you compare methods? Because when the component is rerendered,onClickBInstead, we will continue to update the parts of the company for the first timeonClickBThere is no change, but the component is updated, which is a waste of rendering performance. This is the timeuseCallBackplayed
const onClickB =useCallBack(() => {
      setDataB(o => o + 1);
}, [])
Copy the code
  • This way, we cache the click event after the first render. Its useCallBack core source code will compare this method and the rerender method to be consistent, and if so, return the old method. So you’re going to make sure that you’re doing the same thing. With the MEMO, the render will not be repeated.
  • Then useCallBack’s first function if[]An empty array indicates that the enclosing function will not be updated. If the array has a value, it is updated depending on the change in that value:
const onClickB =useCallBack(() => { setDataB(o => o + 1); }, [params]); // Update the method when param is changedCopy the code

Pay attention to

Since useCallBack is so good, why not cover all methods? The answer is no, since we know that the core principle of useCallBack is to make a comparison between the old method and the rerendered method to determine whether to return the new method. Obviously, if each method is added such a layer, it will result in a waste of comparison for each method, which will waste the performance. If the scene should be used when the responsible component is rendered unnecessarily, do not abuse it.

conclusion

The useCallBack is also understood, which is undoubtedly more handy when using Hook in the future, and has a more solid guarantee on the front end performance optimization level. Hope to continue refueling, die knock front performance optimization.