[React] React 如何自定义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