[React] React 如何自定义Hook

[React] React 如何自定义Hook

      • 为啥要自定义Hook?
      • 如何自定义Hook?

为啥要自定义Hook?

自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook。通过自定义 Hook,可以将组件逻辑提取到可重用的函数中。

如何自定义Hook?

既然Hook是一个函数,那么在编写自定义Hook ,我们需要先想好传入的参数,以及函数的返回值,比如在封装一个请求的自定义Hook时,只有请求的 url 不一样,那么返回什么呢?请求到的数据,还有接口报错的信息, 如下:

// useRequest.js

const useRequest = (url) => {
	return ....
} 

React 官方推荐自定义的 Hooks 使用 use 开头,因为这样的命名规范使得阅读代码的人知道使用它可以做什么事情。这个函数有如下特点:

  • 函数可以接受参数,可以是任何此 hook 所需要的值,甚至是其他 hooks 返回的值。
  • 函数可以有返回值,给任何调用此 hook 的组件使用

接下来我们编写它的业务逻辑,其实在使用自定义 Hooks 多次之后就会发现,函数式组件里的第一行代码到 return 之前的代码都可以直接放到自定义 Hooks 里边,因为它们都属于业务代码,而 return 中的代码负责展示逻辑。

const useRequest = (url) => {
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState();
  const [error, setError] = useState();

  useEffect(() => {
    const loadData = async () => {
      setIsLoading(true);
      try {
        let response = await fetch(url);
        let data = await response.json();
        setData(data);
      } catch (e) {
        setError(e);
      } finally {
        setIsLoading(false);
      }
    };
    loadData();
  }, []);

  return [data, isLoading, error];
 }
export default useRequest

下面是一个倒计时的自定义 hook 封装

// use-count-down.js

import {useEffect, useState} from 'react'
import {useHistory} from 'react-router-dom'

let timer = null

const useCountDown = (second = 60) => {
  const history = useHistory()
  const [time, setTime] = useState(0)

  const clear = () => {
    if (!timer) return

    setTime(0)
    clearInterval(timer)
  }

  useEffect(() => {
    if (!time) {
      clearInterval(timer)
      return
    }

    if (time === second) {
      timer = setInterval(() => {
        setTime(t => --t)
      }, 1000)
    }
  }, [time])

  useEffect(() => {
    clear()

    history.listen(clear)

    return () => clear()
  }, [])

  return [time, setTime]
}

export default useCountDown

参考链接

https://blog.csdn.net/fengqiuzhihua/article/details/103511209

你可能感兴趣的:(React,react.js,javascript,前端)