自定义React`useFetch`钩子-我需要维护多个状态吗?

时间:2018-11-19 20:24:41

标签: reactjs fetch react-hooks

我已经实现了一个自定义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会在内部处理这个问题,我只需要第一个示例?

2 个答案:

答案 0 :(得分:2)

每个自定义钩子将具有其自己的状态,并且不会在同一钩子的不同实例之间共享状态。因此,您无需跟踪哪个状态属于哪个钩子。

钩子只会在不同的实例之间共享逻辑,而不会共享数据,就像HOCs and Render Props

因此第一个示例可以正常工作。

在您的情况下,多次调用useFetch实际上会导致多次调用useState,而React FAQsuseState来解释国家的独立性,这确实回答了您的疑问< / p>

  

React跟踪当前渲染的组件。感谢   Hook的规则,我们知道Hook只能从React调用   组件(或自定义的Hooks-也只能从React调用   组件)。

     

内部有一个与每个内存关联的“内存单元”列表   零件。它们只是JavaScript对象,我们可以在其中放置一些数据。   当您调用类似useState()的Hook时,它将读取当前单元格(或   在第一次渲染期间将其初始化),然后将指针移至   下一个。这是多个useState()每次调用的方式   独立的本地国家。

答案 1 :(得分:0)

我写了一个很好的例子,说明了如何在软件包useFetch中获得更强大的use-http钩子