preface

Since the release of React Hooks, the acceptance of Hooks has varied widely.

For a front-end developer who is used to Hooks, why wouldn’t anyone try Hooks?

Hooks probably haven’t really felt the power yet. Because I tried out the Hooks API when they were first released, but didn’t see much difference between the official website DEMO and the DEMO I wrote and Component.

The difference between Hooks and Component

Many people, like me at first, don’t understand why Hooks are so popular and why they differ from Component.

The biggest difference is that Component is extraction for components, Hooks are extraction for logic. It can be thought of as a responsive common function.

Hooks from popover switches

The front end is certainly no stranger to modal boxes. A website more or less has several modal boxes. For modal box components, we simply implement one:

import * as React from 'react'
import { createPortal } from 'react-dom'

export interface IModalProps {
  visible: boolean
  onClose: (a)= > void
  children: React.ReactNode
}

const Modal: React.FC<IModalProps> = props= > {
    // handle props. Visible and other logic
    // ...
  return createPortal((
    <div className='modal'>
      {props.children}
    </div>
  ), document.body)
}

export default Modal
Copy the code

So when the parent component uses this popover, it needs to click open popover, and click close to close it

Component usage

import * as React from 'react'
import Modal from './Modal'

interface IDemoState {
  visible: boolean
}

class Demo extends React.Component<any.IDemoState> {

  constructor(props: any) {
    super(props)
    this.state = {
      visible: false,
    }
  }

  public render() {
    return (
      <>
        <button onClick={this.open}>
          open modal
        </button>
        <Modal
          visible={this.state.visible}
          onClose={this.close}>
          children
        </Modal>
      </>
    )
  }

  private open = () => {
    this.setState({
      visible: true,
    })
  }

  private close = () => {
    this.setState({
      visible: false,
    })
  }
}
Copy the code

The Function Component way

Use useState in function components instead of State in React Component

import * as React from 'react'
import Modal from './Modal'

const Demo: React.FC = (a)= > {
  const [visible, setVisible] = React.useState(false)

  const open = React.useCallback((a)= > {
    setVisible(true)}, [])const close = React.useCallback((a)= > {
    setVisible(false)}, [])return (
    <>
      <button onClick={open}>
        open modal
      </button>
      <Modal
        visible={visible}
        onClose={close}>
        children
      </Modal>
    </>)}Copy the code

Using useState instead of State in Component reduces the amount of code, but in real development you might have medium modal boxes and lots of visible, open, and close modal box control variables.

Using Hooks

In the previous development of Component, it was difficult to reuse the repeated variables and logic such as visible, open and close, so HOC and other methods were used to solve the problem

Fortunately, Hooks are in, and we extract this part as a useTrigger Hook function

export function useTrigger(initialValue = false) {
  const [visible, setVisible] = React.useState(initialValue)

  const open = React.useCallback((a)= > {
    setVisible(true)
  }, [setVisible])

  const close = React.useCallback((a)= > {
    setVisible(false)
  }, [setVisible])

  return {
    visible,
    open,
    close,
  }
}
Copy the code

So in that case let’s change the use of Modal up here

const Demo: React.FC = (a)= > {
  const trigger = useTrigger()
  return (
    <>
      <button onClick={trigger.open}>
        open modal
      </button>
      <Modal
        visible={trigger.visible}
        onClose={trigger.close}>
        children
      </Modal>
    </>)}Copy the code

Yes, that’s Hooks, const trigger = useTrigger() where Modal is used takes care of a lot of repetitive work.

Other Hooks

There were a lot of things like this in React development, where we spent a lot of time doing repetitive work, such as defining values and handleChange again and again while using input fields, which can also be fixed by Hooks

export function useInputChange(defaultValue = ' ') {
  const [value, setValue] = useState(defaultValue)

  const handleChange = useCallback((evt: React.ChangeEvent) = > {
    const { value } = evt.target as HTMLInputElement
    setValue(value)
  }, [])

  return {
    value,
    handleChange,
  }
}
Copy the code

There are requests for data after the page loads

import { useState, useEffect } from 'react'

export function useFetch(opts) {
  const [loading, setLoading] = useState(true)
  const [data, setData] = useState(null)
  const loadData = async() = > {/ /... Logic such as loading data
  }
  useEffect((a)= > {
    loadData()
  }, [])
  return {
    loading,
    data,
    loadData,
  }
}

const Demo = (a)= > {
    const { data, loading } = useFetch('https://api.com')
    return (
        // ... render data)}Copy the code

There is nothing a Hook can’t solve, if there is, two!

Similarly in Vue, Vue released a vue-functional-API, which is the Vue version of React Hooks, now composition-API