【问题标题】:Custom React `useFetch` hook - do I need to maintain multiple states?自定义 React `useFetch` 钩子 - 我需要维护多个状态吗?
【发布时间】: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


【解决方案1】:

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

Hooks 只会在不同的实例之间共享逻辑而不是数据,很像 HOCs and Render Props

所以第一个例子可以正常工作。

在您的情况下,多次调用 useFetch 基本上会导致多次调用 useStateReact FAQsuseState 解释状态的独立性,这确实回答了您的疑问

React 跟踪当前呈现的组件。非常感谢 Hooks 的规则,我们知道 Hooks 只能从 React 中调用 组件(或自定义 Hooks——也只能从 React 调用 组件)。

每个内存单元都有一个内部列表 零件。它们只是 JavaScript 对象,我们可以在其中放置一些数据。 当你调用 useState() 之类的 Hook 时,它会读取当前单元格(或 在第一次渲染期间初始化它),然后将指针移动到 下一个。这就是多个 useState() 调用每个 get 的方式 独立的地方州。

【讨论】:

    【解决方案2】:

    我写了一个很好的例子,说明你可以在我的包use-http 中为更强大的useFetch 钩子做些什么?

    【讨论】:

      猜你喜欢
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-18
      • 2020-09-20
      • 1970-01-01
      • 2020-11-30
      • 1970-01-01
      相关资源
      最近更新 更多