Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
通过自定义 Hook,可以将组件逻辑提取到可重用的函数中。自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook。
我们要写一个Hook,先要思考它应该具备哪些功能。获取接口数据需要一个超时时间跟踪加载的状态,接口可能本身报错,我们需要进行错误处理。然后编写函数确定输入的参数和输出的结果。
import React, { useState } from 'react';
function useFetchData(utl, timeout) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false)
const [error, setError] = useState(false)
return [data, loading, error]
}
1.我们定义了useFetchData函数,该函数根据自定义Hook命名,并接收url和timeout值2.使用useState定义了请求数据,加载状态和错误状态3.最后返回所有状态变量
接下来开始发送请求
function useFetchData(url, timeout) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false)
const [error, setError] = useState(false)
async function load() {
setLoading(true);
try {
const instance = axios.create();
const result = await instance.get(url, { timeout });
setData(result)
} catch (error) {
setError(true)
}
setLoading(false)
}
return [data, loading, error, load]
}
1.我们将loading设置为true,并且仅在此函数的最后将其设置为false2.我们在实际API调用周围使用了一个try…catch块来捕获所有错误3.我们使用axios库向URL发出实际请求,并提供超时值4.如果获取数据成功,则将数据设置为结果,如果数据获取失败,则将error设置为true
如果仅在函数组件声明中调用load函数会发生什么?该函数将更改组件的状态,从而触发重新渲染,这将再次执行加载,并…
因此,需要从外部调用该函数-我们需要将其导出到使用此钩子的组件。
每当调用该组件时,都应将其状态重置为初始值。
function useFetchData(url, timeout) {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false)
const [error, setError] = useState(false)
function init() {
setData([])
setLoading(false)
setError(false)
}
async function load() {
init()
setLoading(true);
try {
const instance = axios.create();
const result = await instance.get(url, { timeout });
setData(result)
} catch (error) {
setError(true)
}
setLoading(false)
}
return [data, loading, error, load]
}
目前为止,在 React 中有两种流行的方式来共享组件之间的状态逻辑: render props 和高阶组件,现在 Hook 也可以让你不增加组件的情况下解决相同问题的。