因此,我正在构建一个React应用,并且试图简化使用axios的自定义挂钩调用后端api的过程。这个钩子保持加载和错误状态,因此我不必在发出请求的每个组件中都保持该状态。它还公开了一个callApi()函数,该函数发出实际请求,然后更改挂钩中的状态。这是自定义钩子的代码。
import { useState } from 'react'
import axios, { AxiosRequestConfig } from 'axios'
export default <DataType>() => {
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const [data, setData] = useState<DataType>()
async function callApi(config: AxiosRequestConfig) {
setLoading(true)
setError('')
try {
const response = await axios.request<DataType>(config)
setData(response.data)
} catch (error) {
if (error.response) setError(error.response.data.msg)
else if (error.request) setError('A network error occured')
else setError('An error occured')
} finally {
setLoading(false)
}
}
return {
data,
loading,
error,
callApi
}
}
然后我尝试在要发出请求的组件的useEffect挂钩中使用此callApi()方法。
const { data: posts, loading, error, callApi } = useApi<Post[]>()
useEffect(() => {
callApi({
url: 'http://localhost:4000/blog'
})
}, [])
这可以按预期工作,但是我的linter(使用create-react-app设置)发出了以下警告:
React Hook useEffect缺少依赖项:'callApi'。包括它或删除依赖项数组react-hooks / exhaustive-deps 如果我将callApi添加到依赖项数组或完全删除依赖项数组,则会创建一个无限循环,因为callApi会更新状态,而我只想在安装时调用api。
如果我删除依赖项列表或将callApi添加到依赖项列表,则将一直在无限循环中调用效果,而我只想在mount上调用。
该警告应如何解决?代码是否存在任何风险(毕竟,短绒猫抱怨是有原因的)?
答案 0 :(得分:0)
您的useEffect
使用自定义钩子返回的callApi函数。
由于函数可以随组件中的任何道具或状态发生变化,因此React警告您,如果函数会发生变化,则永远不会调用新函数。
如果要消除警告,则应将函数添加到第二个参数数组中。
useEffect(() => {
callApi({
url: 'http://localhost:4000/blog'
})
}, [ callApi ])
答案 1 :(得分:0)
这应该有效:
const callApi = useCallback(async (config: AxiosRequestConfig) => {
setLoading(true)
setError('')
try {
const response = await axios.request<DataType>(config)
setData(response.data)
} catch (error) {
if (error.response) setError(error.response.data.msg)
else if (error.request) setError('A network error occured')
else setError('An error occured')
} finally {
setLoading(false)
}
}), [])
...和...
useEffect(() => {
callApi({
url: 'http://localhost:4000/blog'
})
}, [callApi])
callApi
永不更改,因此将其传递给useEffect
将具有与useEffect(..., [])
相同的行为