Customize hooks, useMemo

Keywords: html5 React

preface

When we want to share logic between two functions, we extract it into the third function. Both components and hooks are functions, so this method is also applicable.

What are hooks and how to use them. Recommended articles:

How to use react hooks?
Play with react hooks, customize hooks design pattern and its actual combat

rule

  • Hook is defined as a function whose name starts with "use". Other hooks can be called inside the function.
  • Use Hook only at the top
  • Do not call Hook in loops, conditions or nested functions.
  • Call Hook only in the React function, instead of calling Hook in the ordinary JavaScript function.

be careful

  • Custom Hook is a kind of convention that naturally follows the design of Hook, rather than the feature of React.
  • Must the custom Hook start with "use"? It must be. This agreement is very important. If you don't follow it, because you can't judge whether a function contains a call to its internal Hook, React will not be able to automatically check whether your Hook violates the Hook rules.
  • Will using the same Hook in both components share the state? can't. Custom Hook is a mechanism for reusing state logic (for example, setting it as a subscription and storing the current value), so every time you use a custom Hook, all States and side effects are completely isolated.
  • How can a custom Hook get an independent state? Each time Hook is called, it gets an independent state.

When writing custom hooks, we should pay special attention to what is passed in and what is returned. What we return is what we really need.

Instance date formatting

function useTimeFormate(time) {
    let date = typeof time === 'string' ? new Date(time) : time
    let year = date.getFullYear()
    let tempMonth = date.getMonth() + 1
    let month = tempMonth > 9 ? tempMonth : '0' + tempMonth
    let tempDay = date.getDate()
    let day = tempDay > 9 ? tempDay : '0' + tempDay

    console.log(1)
    return year + '-' + month + '-' + day
}

export default useTimeFormate
import {useState} from "react"

import useTimeFormate from "../../hooks/time";

function Home() {
    let [num, setNum] = useState(0)
    let time = useTimeFormate("2021-11-30")

    return (
        <div>
            <p>Date formatting:{time}</p>
            <p>The number is:{num}</p>
            <button type='primary' onClick={() => setNum(num + 1)}>add one-tenth</button>
        </div>
    )
}

useMemo

When setting up custom hooks, we must add the condition limitation - performance overhead. The above execution results are as follows: I just want to change the value of num, but when rendering again after the value of num is changed, usetimeformat is also called, which causes a waste of performance.

use

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • Pass the "create" function and dependency array as parameters into useMemo, which recalculates the memoized value only when a dependency changes. This optimization helps to avoid expensive calculations at each rendering.

  • The function passed into useMemo is executed during rendering. Please do not perform rendering independent operations inside this function. Operations such as side effects belong to the applicable scope of useEffect, not useMemo.

  • If no dependency array is provided, useMemo calculates a new value each time it renders.

  • If the second parameter of useMemo(fn, arr) matches and its value changes, it will be executed multiple times. Otherwise, it will be executed only once. If it is an empty array [], fn will be executed only once

Simply transform the hook above

import { useMemo } from "react"

function useTimeFormate(time) {
    return useMemo(() => {
        let date = typeof time === 'string' ? new Date(time) : time
        let year = date.getFullYear()
        let tempMonth = date.getMonth() + 1
        let month = tempMonth > 9 ? tempMonth : '0' + tempMonth
        let tempDay = date.getDate()
        let day = tempDay > 9 ? tempDay : '0' + tempDay

        console.log(1)
        return year + '-' + month + '-' + day
    }, [time])
}

Execution results:


If let time = usetimeformat ("2021-11-30") is changed to let time = usetimeformat (New date()), 1 will be printed every time. It's not wrong here.
As mentioned above, the function passed in useMemo will be executed during rendering. When the num value changes, it will be rendered again. At this time, the value of time will be obtained again. At this time, time is not a dead value, so the remembered value will be recalculated

Posted by asurfaceinbetween on Mon, 29 Nov 2021 10:37:26 -0800