This is the 13th day of my participation in the August More Text Challenge

1 Why use React Hooks

Let’s start with a simple example, now we’ve done a super, super simple example: click the button and increment the number by 1 using what we did before (class defined component)

import React, { Component } from 'react'

 class Increased extends Component {
   constructor (props) {
     super (props) 
     this.state={count:0}}render() {
    return (
      <div>
        <p>Total: {this. State. The count}</p>
        <button onClick={this.add.bind(this)}>increase</button>
      </div>)}add() {
    this.setState({count:this.state.count+1}}})export default Increased

Copy the code

Let’s take a look at this using React Hooks

import React,{useState } from 'react'

const IncreasedHooks = () = > {
  const [ count , setCount ] =useState(0)// Array destruct
  return (
    <div>
       <p>Total: {count}</p>
        <button onClick={()= >SetCount (count + 1)} ></button>
    </div>)}export default IncreasedHooks

Copy the code

Here’s how it looks:

2, rounding useState

UseState is a react hook function that declares state variables. The useState function takes the initial value of the state and returns an array in which bit 0 is the current state value and bit 1 is the method function that can change the state value

  1. How to declare according to the above code know
 const [ count , setCount ] =useState(0)// Array destruct

Copy the code
  1. How to read because we’re returning an array, we just fetch it the way we fetch the elements of the array, and it’s very easy to read. Just use {count}, because count is a variable in JS. If you want to use JSX, add {} to the value. I suggest using deconstruction, simple and quick. What? You can’t deconstruct? So you poke this deconstruct assignment and you have to know that
< p > total: {count} < / p >Copy the code
  1. To change state we use the second value in the returned array
    <button onClick={() = >setCount(count+1)} > add < / button >Copy the code

3 useEffect

3.1useEffect replaces commonly used life cycle functions

UseEffect can be used to replace componentDidMount and componentDidUpdate, so when do we use the lifecycle function? The counter result is printed in the browser console after the first rendering of the component and the knot is printed after each counter state change, respectively

There are two things to note when using useEffect

  • React The useEffect function is called for the first rendering (componentDidMonut) and for every subsequent rendering (componentDidUpdate).

  • UseEffect defines functions that execute asynchronously without preventing the browser from updating the view, whereas the code in componentDidMonut and componentDidUpdate are executed synchronously. Personally, I think this has both advantages and disadvantages. For example, we need to draw the size of the current pop-up window according to the size of the page. If it is asynchronous, it will be difficult to operate.

const IncreasedHooks = () = > {
  const [ count , setCount ] =useState(0)
  useEffect(() = >{
    console.log(`useEffect=>You clicked ${count} times`)})// Resolve the life cycle function instead of componentDidMount and componentDidUpdate. The counter result is printed in the browser console after the first rendering of the component and the knot is printed after each counter state change, respectively

  return (
    <div>
      <div>Use the React Hooks</div>
       <p>Total: {count}</p>
        <button onClick={()= >SetCount (count + 1)} ></button>
    </div>)}Copy the code

3.2 Implement something like componentWillUnmount (executed when the component is about to be unmounted)

Use route to implement component unbinding, need to use the useEffect function in the form of a return function, instead of unbinding life cycle function componentWillUnmount component is about to be unmounted to execute


 const Index = () = > {
  useEffect(() = >{
    console.log('useEffect=> There you are, buddy! The Index page ')
    return () = >{
    console.log('Buddy, you're gone! The Index page ')}// Returns a function in the form of a function instead of the untying life cycle function componentWillUnmount when the component is about to be unmounted}, [])return <div>Come on, programmers</div>
}
const List = () = >{
  return (
    <ul>
      <li>hello</li>
      <li>I am good</li>
      <li>He is good</li>
    </ul>)}const IncreasedHooks = () = > {
  return (
    <div>   
      <Router>
        <ul>
          <li><Link to = "/">Home page</Link></li>
          <li><Link to = "/list/">List of pp.</Link></li>
        </ul>
        <Route path ="/" exact component={Index}></Route>
        <Route path ="/list/" component={List}></Route>
      </Router>
    </div>)}Copy the code

In fact, this is mainly the useEffect of the second parameter, the above program, not when using the second parameter. UseEffect is bound every time the state changes. The second argument to useEffect is an array that can be used to write variables corresponding to the state, meaning that the unbinding is performed only when the state value changes. But when an empty array [] is passed, the component is unbound only when it is about to be destroyed, which implements the life cycle function for componentWillUnmount.

The second parameter is the implementation unbinding condition

For example, to unbind the counter as well: simply write the count variable, the state value of the record count, to the returned array

const IncreasedHooks = () = > {
  const [ count , setCount ] =useState(0)// Array destruct
    useEffect(() = >{
        console.log(`useEffect=>You clicked ${count} times`)

        return () = >{
            console.log('= = = = = = = = = = = = = = = = = = = =')
        }
    },[count])
  return (
    <div>
       <p>Total: {count}</p>
        <button onClick={()= >SetCount (count + 1)} ></button>
    </div>)}Copy the code

4 Using useContext

UseContext is used to transfer values between parent and child components

import React,{useState ,useContext, createContext } from 'react'
const CountContext = createContext()

// Define child components
const Coounter = () = >{
   // The child component can get the count passed by the parent in a single sentence
const count = useContext(CountContext)
return (<h2>{count}</h2>)}/ / the parent component
const IncreasedHooks2= () = > {
  const [ count , setCount ] =useState(0)
  return (
    <div>
      <div>Use the React Hooks</div>
       <p>Total: {count}</p>
        <button onClick={()= >SetCount (count + 1)} ></button>{/* Parent component provides value to component */}<CountContext.Provider value={count} >
          <Coounter/>
        </CountContext.Provider>
    </div>)}export default IncreasedHooks2

Copy the code

5 Use of useReducer

5.1 Achieve reducer when useReducer is Deployed

UseContext can cooperate with useReducer to complete similar operations of the Redux library. UseReducer can make the code more readable and maintainable. It is similar to reducer and Reducer functions in Redux, which receive two parameters, one is state, and the other is state. A decision parameter to control business logic A simple reducer example to understand what reducer is

function countReducer(state, action) {
    switch(action.type) {
        case 'add':
            return state + 1; 	
        case 'sub':
            return state - 1;
        default: 
            returnstate; }}Copy the code

Using useReducer

import React, { useReducer } from 'react';

const IncreasedHooks2 = () = > {

  const [count, dispatch] = useReducer((state, action) = > {
    switch (action) {
      case 'add':
        return state + 1
      case 'sub':
        return state - 1
      default:
        return state
    }
  }, 0)
  return (
    <div>
      <h2>Now the score is {count}</h2>
      <button onClick={()= > dispatch('add')}>Increment</button>
      <button onClick={()= > dispatch('sub')}>Decrement</button>
    </div>)}export default IncreasedHooks2

Copy the code

5.2 useReducer useContext Manages and shares redux status

Achieve global status and unified management, unified event distribution

Case: Click the button to switch the corresponding font color

/ / the parent component
import React from 'react';
import Buttons from './Buttons';
import ShowArea from './ShowArea'
import { Color } from './Color';   // Introduce the Color component
const ChangeColor = () = > {
  return ( 
  <div>
    <Color>
      <Buttons />
      <ShowArea />
    </Color>
  </div>)}export default ChangeColor

// Font display component
import React,{useContext} from 'react'
import { ColorContext } from './Color';

const ShowArea = () = > {
  / / for color
  const {color} = useContext(ColorContext)
  return ( 
    <div>
      <div style={{color:color}}>Font color is {color}</div>
    </div>)}export default ShowArea

// Button component
import React ,{useContext} from 'react';
import {ColorContext,UPDATE_COLOR} from './Color'
const Buttons = () = > {
  // Get the dispatch of the share
  const {dispatch} = useContext(ColorContext)
  return ( 
    <div>{/* Dispatch an action */}<button onClick= {()= >{dispatch ({type: UPDATE_COLOR, color: "red"})}} > red</button>
    <button onClick= {()= >{dispatch ({type: UPDATE_COLOR, color: "yellow"})}} > yellow</button>
</div>)}export default Buttons


// State management
import React,{createContext ,useReducer } from 'react'
export const ColorContext = createContext()
export const UPDATE_COLOR = "UPDATE_COLOR"
/ / define reducer
const reducer = (state, action) = > {
  switch (action.type) {
    case UPDATE_COLOR:
     return action.color
    default:
     return state
  }
}
// Color sharing
export  const Color = props= > {
  / / use reducer
const [color, dispatch] = useReducer(reducer,'red')

  return ( 
    <div>{/* Share color with dispatch */}<ColorContext.Provider value={{color,dispatch}}>
        {props.children}
      </ColorContext.Provider>
    </div>
   );
}
 
 

Copy the code

The results of

6. useMemo

Function components have shouldCompnentUpdate, there is no way to determine whether a component is updated by a condition before it. There is no longer a distinction between mount and update states in function components, which means that every call to a function component executes all the internal logic, resulting in a significant performance penalty. Both useMemo and useCallback address these performance issues


import React , {useState,useMemo} from 'react';

function ComeHere(){
    const [he, setHe] = useState('He's waiting.')
    const [me, setMe] = useState('I'm waiting')
    return (
        <>
            <button onClick={()= >{setHe (new Date (). GetTime ())}} ></button>
            <button onClick={()= >{setMe(new Date().gettime ()+', I'm coming ')}}> ME</button>
            <ChildComponent name={he}>{me}</ChildComponent>
        </>)}function ChildComponent({name,children}){
    function changeHe(name){
        console.log('Here she comes, here she comes. He's coming to us. ')
        return name+'He's coming to us.'
    }
// To solve the problem that when we click the "I" button, the changeHe method corresponding to "he" cannot be executed, only when we click the "he" button. To reduce the number of useless re-renders of child components
// If the second parameter matches, it will be executed.
    const actionHe = useMemo(() = >changeHe(name),[name]) 
    return (
        <>
            <div>{actionHe }</div>
            <div>{children}</div>
        </>)}Copy the code

7. useRef

  • Get the React JSX DOM element with useRef. Once you get it, you can control anything in the DOM. However, this is not recommended. The React interface changes can be controlled by state.

  • Using useRef to save variables, which is also rarely used in the workplace, doesn’t really make sense when we have useContext

import React, { useRef} from 'react';
function Example(){
// Declare an input element
    const inputEl = useRef(null)
    const onButtonClick=() = >{ 
        inputEl.current.value="Hello ,JSPang"
        console.log(inputEl) // Output the DOM node
    }
    return (
        <>{/* Save input ref to inputEl */}<input ref={inputEl} type="text"/>
            <button onClick = {onButtonClick}>Display text on input</button>
        </>)}export default Example

Copy the code

8. Customize Hooks functions

For example, customize the Hooks function from the first Hooks function that monitors the browser window size in real time, remember to start with use

import React,{ useState ,useEffect ,useCallback } from 'react';
const useWinSize = () = >{
  const [size,setSize] = useState({
    width:document.documentElement.clientWidth,
    height:document.documentElement.clientHeight
  })
//useCallback is for caching methods (useMemo is for caching variables)
  const onResize = useCallback(() = > {
    setSize({
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight
  })
  },[])
  useEffect(() = >{
    window.addEventListener('resize',onResize)
    return () = >{
      window.removeEventListener('resize',onResize)
  }
  },[])
  return size
}

// used in the component
const MyHooks = () = >{
  const size = useWinSize()
return <div>size:{size.width}x{size.height}</div>
}
export default MyHooks


Copy the code