【发布时间】:2019-04-22 06:06:34
【问题描述】:
我已经实现了一个自定义的 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
然后我突然想到...这将在整个应用程序中使用。它如何知道哪个 data/loading/error 属于哪个调用?当我第一次使用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 在其内部处理这个问题,而我只需要第一个示例?
【问题讨论】:
-
自定义挂钩用于共享有状态逻辑,而不是状态。所以按照你的第一个 sn-p 的思路就可以了。
-
@Tholle 好点。我想这很难打破旧习惯!
标签: reactjs fetch react-hooks