Application scenarios

Sometimes calculation of some functions may be complicated and time-consuming, but there is no mount and update for the function component itself, that is, as long as setState is called, no matter whether the value of state before and after it is different, the re-rendering of the component will be triggered. After the first rendering, how to cache the calculation result of this function? As long as the dependency remains unchanged, it does not create a new object for the function, but points to the same reference. In this case, useMemo is required to implement it. Wrap this code around useMemo.

The parent component updates, and the child component updates automatically. We want the child component not to be rendered, even if the parent component is rendered, when the props and state of the child component are not changed. UseCallback is needed to reduce unnecessary child component rerendering. We often define a callback function in the parent component to pass to the child component. How to prevent this callback function from causing unnecessary rendering of the child component? To do this, we can define a piece of logic code in the parent component, wrapped in useCallback. In this logic code, we can write the relevant setState and other code that causes the parent component to re-render, and then pass this function to the child component through props. The child component will not cause the parent component to render because of the code executed inside the function. This effectively avoids unnecessary re-rendering of child components; The child component is rerendered only if the function dependency changes and the function recreates the new object. (I understand that the parent component callback function used by the child component is time-consuming, so we need to consider using useCallback to control the performance problems caused by the parent component callback function passing arguments.)

In most cases, react is efficient, so performance can be ignored for the time being and optimization can be done when necessary.

UseMemo: The return result of the cache function is targeted at optimizing the current component, i.e., an optimization strategy that performs costly computations every time it renders.

useCallback: It is used to cache the function, which is usually used to define the callback function between parent and child components as a parameter. How to avoid the parent component’s callback function causing unnecessary child component rendering. In fact, the cache is the memory reference address of the function, the parent component defines the callback function that needs to be passed to the child component. The code inside this callback performs such parent component rendering caused by setState. As long as the dependencies remain unchanged, the child component will not be re-rendered. The optimization strategy of locating the callback function in the parent component to perform expensive computations when it needs to be called to the child component through the functions.

features

  • UseEffect is a side effect function that executes after the component is rendered (it can be controlled), whereas useMemo and useCallback have no control over whether or not to execute. Functions that are executed during each rendering (as long as you define and reference them in the function component, when setState is executed, the component will re-render causing the function to execute, how to control dependencies that do not change, the computationally-complex function is not executed, but instead uses the cached result of the earlier function’s calculation. This is the main function of useMemo and useCallback.

  • In order to improve the performance of this component, useMemo avoids indiscriminately executing computationally time-consuming functions during component rendering (which do not need to be recalculated if the dependency does not change most of the time, and the dependency (i.e. the second parameter) selects the state that does not change frequently).

  • UseCallback used more often in the child component rendering control on the parent component rendering, some of the time don’t need to render the child components, then can let the child components to receive a function as props (equivalent to tell the child components, only this item function dependency changes only need apply colours to a drawing, or parent component rendering has nothing to do with the child component.

  • Common: useMemo takes the same arguments as useCallback. The first argument is a callback function and the second argument is a dependency value group. You need to create a new function object only when the dependency changes.

  • Differences: useMemo locates the optimization of this component to avoid repeated execution of logically complex calculations; UseCallback locates how to effectively avoid unnecessary rendering of child components.

  • Internal execution of either useMemo or useCallback functions. Since this function is executed during rendering, do not perform non-rendering operations inside this function. Operations such as side effects are used by useEffect, not useMemo.

  • The second parameter of useMemo and useCallback, the array of dependency values, should be planned scientifically and changed as little as possible, otherwise the cache is useless.

The official advice: Write code that can run without useMemo and useCallback first, and consider them later when tuning performance as needed.

grammar

There are two parameters:

The first argument is a function that returns an object to the same reference and does not create a new object. The second argument is an array, and the function of the first argument returns a new object only if the variables in the array change. UseMemo grammar:

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

const memoizedCallback = useCallback( () => { doSomething(a, b); }, [a, b], );

Usage examples

UseMemo example: a state is computed by a function (which is a time-consuming function), the data returned by this calculation is cached, and the function needs to be re-executed only if the dependency value group changes, otherwise the cached data can be referenced directly during each rendering.

function Example() { const [count, setCount] = useState(1); const [val, setValue] = useState(”);

const getNum = useMemo(() => { return Array.from({length: The count * 100}, (v, I) = > I). The reduce ((a, b) = > a + b)}, [count]) return < div > combined: {getNum()} <div> <button onClick={() => setCount(count + 1)}>+1</button> <input value={val} onChange={event => setValue(event.target.value)}/> </div> </div>;Copy the code

}

UseCallback example: The parent component’s callback function plus useCallback prevents unnecessary rendering of the child component. Only the parent component’s function dependency changes. The internal code logic of the function causes the parent component to be re-rendered independently of the child component. The child component is only a reference to the function address, i.e. the function instance and dependency are one-to-one.

The parent component defines a callback function, wrapped in useCallback, and passes this callback function to the child component, telling the child component that it needs to re-render only if the dependency of this callback function changes. Otherwise, the parent component rendering does not matter to the child component.

The parent component defines the callback function, which is passed to the child component, and the child component calls this function. This callback function is added to the useCallback to avoid the setState inside the parent component’s callback function causing the parent component to render unnecessarily. In my understanding, this optimization is only necessary if the subcomponent itself is also time-consuming, otherwise the rendering speed of the subcomponent will not cause performance problems.

function Parent() { const [count, setCount] = useState(1); const [val, setValue] = useState(”);

const getNum = useCallback(() => {
    return Array.from({length: count * 100}, (v, i) => i).reduce((a, b) => a+b)
}, [count])

return <div>
    <Child getNum={getNum} />
    <div>
        <button onClick={() => setCount(count + 1)}>+1</button>
        <input value={val} onChange={event => setValue(event.target.value)}/>
    </div>
</div>;
Copy the code

}

Const Child = react. memo(function ({getNum}: any) {return sum: {getNum()}})