我已经实现了一个自定义useFetch
钩子,所以在我的应用程序中获取:
import { useEffect, useState } from 'react'
const useFetch = ({ url, defaultData = null }) => {
const [data, setData] = useState(defaultData)
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(res => {
setData(res)
setLoading(false)
})
.catch(err => {
setError(err)
setLoading(false)
})
}, [])
return [data, loading, error]
}
export default useFetch
然后我突然想到......这将在整个应用程序中使用。它如何知道哪个数据/加载/错误属于哪个调用?当我useFetch
第一次使用,然后在应用程序的其他地方紧随其后,React 是否会跟踪哪些内部状态变量属于哪个钩子调用?
然后我想也许我需要沿着 Redux 线做更多的事情,并在钩子的帮助下自己跟踪对自定义钩子的所有调用useReducer
:
import { useEffect, useReducer } from 'react'
const reducer = (state, action) => {
const { url, data, err } = action
const currentState = state[url]
switch (action.type) {
case 'fetching':
return { ...state, [url]: { ...currentState, loading: true } }
case 'success':
return { ...state, [url]: { ...currentState, loading: false, data } }
case 'fail':
return { ...state, [url]: { ...currentState, loading: false, err } }
default:
return state
}
}
const useFetch = ({ url, defaultData = null }) => {
const [state, dispatch] = useReducer(reducer, {}, { type: 'fetching', url })
const { data: d, loading: l, err: e } = state[url]
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => dispatch({ type: 'success', url, data }))
.catch(err => dispatch({ type: 'fail', err }))
}, [])
return [d || defaultData, l, e]
}
export default useFetch
我是否需要像第二个示例中那样手动跟踪对useFetch
自己的所有呼叫?还是 React 在其内部处理这个问题,而我只需要第一个示例?