Introduction to the

Hook is a new feature in Act 16.8 that lets you use features such as state, lifecycle, and so on without writing a class component.

motivation

Reusing state logic between components is difficult

There are some solutions to this problem, such as render props, higher-order components, Context, etc., that cause a tree of components to form a nested hell (a bit like the way callback functions and flutter are written).

With hooks, you can extract state logic from components so that it can be individually tested and reused. Hooks allow you to reuse state logic without modifying the component structure.

Complex components become difficult to understand

As the business expands, the number of logical states and side effects within components increases. When we write a class component, we usually put the data fetch in compoentDidMount and componentDidUpdate, and when it comes to timers or data subscriptions, You also need to clear timers or unsubscribe data in the life cycle function compoentWillUnmount. This makes the combination of completely unrelated code very buggy and illogical.

To solve this problem, hooks break the interrelated parts of a component into smaller functions (such as setting up subscriptions or requesting data) rather than enforcing a lifecycle partition.

Hard to understand class

Previously, if you wanted to use features like state, life cycles, etc., you had to introduce class components, and if you wanted to use them you had to take the time to understand how this works in JavaScript.

To address these issues, hooks allow you to use more React features in non-class situations.

An overview of

Hooks can be divided into built-in hooks and custom hooks.

Built-in hooks include:

  • useState
  • useEffect
  • useContext
  • useReducer
  • useCallback
  • useMome
  • useRef
  • useImperativeHandle
  • useLayoutEffect
  • useDebugValue

A custom Hook is a combination of the above built-in hooks and exported as a function starting with use.


Here we write a class based Counter component, let’s Hook it later.

import React from 'react'



class Counter extends React.Component {

  constructor(props) {

    super(props)

    this.state = { count0 }

    this.setCount = this.setCount.bind(this)

  }



  setCount() {

    this.setState({

      countthis.state.count + 1

    })

  }

  

  render() {

    return (

      <>

        <h2>{ this.state.count }</h2>

        <button onClick={ this.setCount} >+</button>

      </>


    )

  }

}

Copy the code

useState

Let’s take a look at one of the most basic and equally important hooks, and now let’s start transforming the class component above.

  • First of all toclassComponents tofunctionComponents, that isFunctional component.
- class Counter extends React.Component {}



+ function Counter() {}

Copy the code
  • So let’s move onstateAnd other relevant code to delete, insteaduseStateHook, because there are many changes here, directly on the final code
import React, { useState } from 'react'



const Counter = (a)= > {

  // Array destruct syntax

  // Declare a count variable and declare a setCount function to change the value of count

  const [count, setCount] = useState(0)

  

  return (

    <>

      <h2>{ count }</h2>

      <button onClick={() = > setCount(count + 1) }>+</button>

    </>


  )

}

Copy the code

At first glance, the code looks much cleaner, which is exactly what we want. (Hook smells good)

If we have more than one state variable, we can write it in the following form

const [count, setCount] = useState(0)

const [num, setNum] = useState(0)

const [name, setName] = useState(' ')

.

Copy the code

If this update depends on the last state value, it can be written that setCount takes a function as an argument

const [count, setCount] = useState(0)



const handleClick = (a)= > {

  setCount(prev= > prev + 1)

}



<button onClick={ handleClick }>+</button>

Copy the code

useEffect

UseEffect allows you to perform side effects on a functional component. It takes two arguments, the first being the required side effect function and the second being the optional argument (which is an array of dependencies that the side effect function executes).

Again, if we want to perform some side effects after the component is updated, such as printing the value of the current count variable, or changing the title of the current page

// ...

const [count, setCount] = useState(0)

const [num, setNum] = useState(0)



useEffect((a)= > {

  console.log('The current count value,${count}`)

  document.title = 'The current count value,${count}`

})

// ...

Copy the code

In the code above we can see that we did not add a second optional argument, which means that this side effect function is executed whenever the state in the component changes (not just when count, but even when num changes). If we want the side effect function to be executed only when count changes, then our second argument will come in handy ()

// ...

// The current effect function only depends on the change of count, and is not executed when num changes

// equivalent to compoentDidMount and componentDidUpdate in the class component

useEffect((a)= > {

  console.log('The current count value,${count}`)

  document.title = 'The current count value,${count}`

}, [count])

// ...

Copy the code

If we only want the side effects function to execute when the component is mounted (compoentDidMount)

The useEffect convention, in which an empty array is passed as the second argument, executes the current side effect function only when the component is mounted

useEffect((a)= > {

  console.log('The current count value,${count}`)

  document.title = 'The current count value,${count}`

}, [])

Copy the code

Sometimes we might use a timer, like updating the time every second

const [time, setTime] = useState(new Date())



const timer = null

useEffect((a)= > {

  timer = setInterval((a)= > {

    setTime(new Date())

  }, 1000)

})

Copy the code

UseEffect returns a function that is automatically executed when the component is uninstalled. UseEffect returns a function that is automatically executed when the component is unloaded. You can clear things like timers

const [time, setTime] = useState(new Date())



const timer = null

useEffect((a)= > {

  timer = setInterval((a)= > {

    setTime(new Date())

  }, 1000)

  

  // similar to compoentWillUnMount

  

  // It can also be a named function

  return (a)= > {

    clearInterval(timer)

    timer = null

  }

})

Copy the code