The React Hook guide

What is a Hook?

Hook is a new feature in React 16.8. It lets you use state and other React features without having to write a class.

A Hook is essentially a function that simplifies components, has its own state management, lifecycle management, and state sharing.

  • useState
  • useEffect
  • useContext
  • useReducer

What has the Hook solved?

  • Reuse of state between components, for example, using useContext is a good way to solve the problem of state reuse, or customize HookTo customize state management to suit your business scenario.
  • Use of life cycles in functional components, better design encapsulates components. Life cycles cannot be used directly in function components, through HookA good solution to this problem.
  • The difference between a functional component and a class component also distinguishes the usage scenarios of the two components. use HookDon’t even think about it. It can use more ReactNew features.

When to use Hook?

  1. Called at the top level of a function component

  2. Use/custom in functions HookThe use of

ReactThe built-in Hook

    1. useStateState management
    1. useEffectLife cycle management
    1. useContextSharing status data
    1. useMemoThe cache value
    1. useRefGet Dom operation
    1. useCallbackCache function
    1. useReducerSimilar story
    1. useImperativeHandleChild components expose values/methods
    1. useLayoutEffect Completion of the side effect operation will block the browser drawing

useStateState management

In the class component, we get state through this.state.

In the function component, there is no this. We can use the useState provided by Hook to manage and maintain state.

useStateDefinition/Use

const [state, setState] = useState(initialState)

  • SetState is the update SATate method
  • UseState (initialState) initialState is the initial value

Complete chestnuts

import {useState} from 'react';

export default() = > {const [data, setData] = useState('wechat Public Account: Front-end Self-learning Community')
    return (
        <div>
            <h1>{data}</h1>{/* Update state */}<button onClick={()= >{setData(' wechat public number: front-end self-learning community 666')}}></button>
        </div>)}Copy the code

useEffectLife cycle management

define

UseEffect can be thought of as lifecycle management for functional components.

Because life cycles cannot be used directly in functional components, hooks must be managed to manage usage.

UseEffect has three lifecycle functions that can be used:

  • componentDidmount
  • componentDidUpdate
  • componentWillUnmount

Don’t need to remove Effectuse

What does not need to be clearedEffectUse?

React runs some extra code after updating the DOM

So it just executes in compoentDidmount and componentUpdate of the life cycle.

    useEffect(() = > {
        // It will be executed by default
        // This block corresponds to the class component lifecycle
        //compoentDidmount compoentDidUpdate
    }, [])
Copy the code

removeEffectuse

1. What is clearanceEffect

The Class component lifecycle componentUnmount is used when a component is unmounted and some event handling needs to be performed.

It is easy to use in useEffect by returning a method internally and writing the corresponding business logic in the method

2. Why are you here EffectReturns a function in?

This is the optional clearing mechanism for Effect. Each effect can return a cleanup function. This puts the logic for adding and removing subscriptions together. They are all part of Effect.

    useEffect(() = >{
        return () = > {
            console.log('Execute when component unloads')}})Copy the code

Listening to the statechange

The corresponding business logic can be implemented by controlling listening state changes.

    useEffect(() = > {
        // Listen for num and count status changes
        // Empty when not listening [], or do not write
    }, [num, count])
Copy the code

Complete chestnuts

import { useState, useEffect } from 'react';

export default() = > {const [num, setNum] = useState(0)
    const [count, setCount] = useState(1)

    useEffect(() = > {
        // It will be executed by default
        // This is equivalent to the compoentDidmount compoentDidUpdate for the life cycle of the class component
        console.log(`num: ${num}`)
        console.log(`count: ${count}`)

        // When the component is unloaded, the contents of the return will be executed
        return () = > {
            // Equivalent to the class component life cycle componentWillUnMount
            console.log('test')
        }
    }, [num])

    return (
        <div>
            <h1>{num}</h1>
            <button onClick={()= >{setNum(num + 1)}}> Update num</button>
            <hr />
            <h1>{count}</h1>
            <button onClick={()= >{setCount(count + 1)}}> Update count</button>
        </div>)}Copy the code

useRef

What is the useRef ?

UseRef returns a mutable REF object whose property current is initialized as the passed parameter (initialValue), and the returned REF object remains unchanged throughout the life of the component.

Function:

  1. Get Dom operations, such as getinputThe focus of

  2. Get instances of child components (only class components are available)

  3. A global variable in a function component is not declared repeatedly for repeating render

chestnuts

import {useRef} from 'react';


export default() = > {const inputRef = useRef({value:0})
    return (
        <div>
            <h1>test</h1>
            <input type="text" ref={inputRef} />
            <button onClick={()= >{console.log(inputref.current.value)}}> Get the input value</button>
            <button onClick={()= >{inputref.current. Focus ()}}> Get the input focus</button>
        </div>)}Copy the code

useContextStatus data sharing

ContextWhat was solved

In daily development, we use props to communicate with parent and child components. If we encounter cross-level component communication, we can’t handle it with props.

How can component state be shared?

  • Context
  • Redux
  • .

This section passes ContextTo achieve component data sharing

What is the Context

Data sharing, where any component can access the Context data.

React uses prop to transfer component data from top to bottom. To transfer data globally, use Context.

Note:

Context is mainly used when many components at different levels need to access the same data. Use caution because this makes components less reusable.

create Context

To use the Context, you have to create it, you can create a separate file for it to manage the Context,

import React from 'react';

export const MyContext = React.createContext();

Copy the code

use Context

When Context is used, it is usually used on top-level components (parent components), and the internal components it wraps can enjoy the use and modification of state.

The Context.Provider is wrapped, and the value is passed through value = {}.

How are subcomponents used ContextThe value that was passed in?

  • through useContext()Hook can be very convenient to get the corresponding value.
// Context.js
import React from 'react';

export const MyContext = React.createContext();
Copy the code
import { useContext } from 'react';
import {MyContext} from '.. /Context/index'

const result = {
    code:200.title:'Data added successfully'
}
const Son = () = > {
    const res = useContext(MyContext)
    return (
        <>
            <div>
                <h1>{res.code}</h1>
                <hr/>
                <h2>{res.title}</h2>
            </div>
        </>)}export default() = > {return (
        <MyContext.Provider value={result}>
            <div>
                <h1>Front-end self-learning community</h1>
                <Son/>
            </div>
        </MyContext.Provider>)}Copy the code

useMemoPerformance enhancement optimization

define

UseMemo is used for performance optimization, memorizing values to avoid costly calculations on each render.

UseMemo parameters:

  • useMemoThe return value ismemoizedValue for caching
  • arraycontrol useMemoAn array to be reexecuted,When the state in array changesBefore it is re-executed useMemo

Note:

    1. No array is passed, every update is recalculated
    1. An empty array is evaluated only once
    1. Depends on the corresponding value, and recalculates when the corresponding value changes (you can rely on the value returned by another useMemo)

chestnuts

import { useState, useMemo} from 'react';


export default() = > {const  [count, setCount] = useState(0)
    const [num, setNum] = useState(0)
    const newValue = useMemo(() = >{
        console.log(` count value is${count}`)
        console.log(` num value is${num}`)
        return count+num
    },[count])
    return(
        <div>
            <h1>{count}</h1> 
            <button onClick={()= >{setCount(count+1)}}>count + 1</button>
            <hr/>
            <h1>{num}</h1> 
            <button onClick={()= >{setNum(num+1)}}>Num + 1</button>
            <hr/>
            <h2>{newValue}</h2>
        </div>)}Copy the code

Parsing the chestnuts

When num is updated five times, newValue is always displayed as 0. Why?

When the count value changes, the newValue on the page will be recalculated. Although you have clicked num 5 times, the page is not updated, but it has been cached. When you click to update count, It evaluates the value of count+1 and the value of the num cache, resulting in 5.

Reduced computation cost.

useCallbackPerformance enhancement optimization

define

UseCallback is the syntactic sugar of useMemo. UseCallback can be used to implement useMemo. It is often used to optimize react performance.

UseCallback parameters:

  • callbackIs a function for processing logic
  • arraycontroluseCallbackAn array to be reexecuted,Array is changedBefore it is re-executeduseCallback

use

It is used in the same way as useMemo, except for the function returned by useCallback.

import { useState, useCallback} from 'react';


export default() = > {const  [count, setCount] = useState(0)
    const [num, setNum] = useState(0)
    const newValue = useCallback(() = >{
        console.log(` count value is${count}`)
        console.log(` num value is${num}`)
        return count+num
    },[count])
    return(
        <div>
            <h1>{count}</h1> 
            <button onClick={()= >{setCount(count+1)}}>count + 1</button>
            <hr/>
            <h1>{num}</h1> 
            <button onClick={()= >{setNum(num+1)}}>Num + 1</button>
            <hr/>{/* The value returned by calling useCallback */}<h2>{newValue()}</h2>
        </div>)}Copy the code

summary

UseMemo and useCallback have similar functions to improve performance.

Which approach is best practice remains to be explored.

Readers are welcome to talk to me.


For onlineuseMemo useCallbackOpinion?

UseCallback should be used as a best practice in functional components, but in addition to caching callbacks that depend on unchanged dependencies (similar to useMemo), it is also used to ensure that callbacks are always the latest instance when dependencies change. Without causing any unexpected problems, I feel that the latter is the starting point for using useCallback, not caching. Because even if you don’t use useCallback, assuming that this callback doesn’t have any dependent state, can’t I just declare this function outside of the component? Wouldn’t it be more free if I just used ref?

UseMemo’s name is associated with the cache, and it’s essentially to solve one thing: don’t create objects or methods directly in Render, because every time a component renders, it creates one (like style or some constant state), resulting in an unnecessary waste of resources. Ideally, a dependency should be recreated only when the dependency changes if it exists, and only once if it does not. On the face of it, there is nothing wrong with using useMemo for all states, but you need to look at the cost of caching. If the cost of using useMemo to cache a state outweighs the benefits, is it counterproductive?

Everyone touseMemo useCallbackFeel free to comment below or add me to your thoughts.

useImperativeHandle

define

UseImperativeHandle allows you to customize the instance value exposed to the parent component when using a ref. In most cases, imperative code like ref should be avoided. UseImperativeHandle should be used together with the forwardRef.

UseImperativeHandle role:

A child component can be exposed to a parent component instance

Format: useImperativeHandle (ref, () = > {}, [])

  • Parameter 1: Instance of child component exposed to parent component

  • Parameter 2: function, passed instances and methods that the parent component can operate on

  • Parameter 3: Monitor status and update status



import {useState,useImperativeHandle, forwardRef,useRef} from 'react';


const Son = forwardRef( (props,ref) = > {
    const inputRef = useRef(0)
    const domRef = useRef()
    const [state, setState] = useState('wait')
    useImperativeHandle(ref,() = >({
        focus:() = > {inputRef.current.focus()},
        domRef
    }))
    return (
        <div>
            <h1>{state}</h1>
            <hr/>
            <input type="text" ref={inputRef}/>
            <h2  ref={domRef}>Test -- -- -- -- -- -- -- -- -- useImperativeHandle</h2>
        </div>)})export default() = > {const refFather = useRef(0)
    return (
        <div>
            <h1>The parent component</h1>
            <Son ref={refFather} />
            <button onClick={()= >{refFather.current. Focus ()}}> Get the child component instance ------ get the input focus</button>
            <button onClick={()= >{the console. The log (refFather. Current. DomRef. Current. The innerHTML)}} > get child component instance -- -- -- -- -- - to get the h2 Dom</button>
        </div>)}Copy the code

useReducer

define

It is an alternative to useState. It receives a Reducer of the form (state, action) => newState and returns the current state and its accompanying dispatch method.

If you are familiar with the use of Redux, you are familiar with the use of useReducer.

useReducerImplement an addition and subtraction

import {useReducer} from 'react';


export default() = > {const [state, dispatch] = useReducer((state,action) = > {
        switch (action.type){
            case 'addNum':
                return {
                    num:state.num+1
                }
            case 'subtractNum':
                return {
                    num:state.num-1}}}, {num:0
    })
    return (
        <div>
            <h2>{state.num}</h2>
            <button onClick={()= >{dispatch ({type: "addNum"})}} > increase the num</button>
            <button onClick={()= >{dispatch ({type: 'subtractNum'})}} > num</button>
        </div>)}Copy the code

conclusion

❤️ attention + like + collection + comment + forward ❤️, original is not easy, encourage the author to create better articles pay attention to the public number “front-end self-study community”, you can get more front-end high-quality articles! After paying attention to the reply keyword “add group”, you can join the “front-end self-study communication group”, learning progress together. After paying attention to add my wechat pull you into the technical exchange group welcome to pay attention to the public number, more wonderful articles only in the public number push