Пользовательский хук React `useFetch` - нужно ли поддерживать несколько состояний?

Я реализовал собственный хук 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, как во 2-м примере? Или React справляется с этим внутренне, и мне нужен только 1-й пример?

Пользовательские хуки предназначены для совместного использования логика с сохранением состояния, а не государство. Так что что-то вроде вашего первого фрагмента будет работать нормально.

Tholle 19.11.2018 21:27

@Tholle Хороший вопрос. Я думаю, что ломать старые привычки сложно!

The Qodesmith 19.11.2018 21:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
4
2
1 929
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Каждый настраиваемый перехватчик будет иметь собственное состояние и не будет разделять состояние между разными экземплярами одного и того же перехватчика. Следовательно, вам не нужно отслеживать, какое состояние принадлежит какому хуку.

Хуки будут разделять только логику, а не данные между разными экземплярами, как и HOCs and Render Props.

Итак, первый пример подойдет.

В вашем случае несколько вызовов useFetch по существу приведут к нескольким вызовам useState, а Ответы на часто задаваемые вопросы объясняет независимость состояния с помощью useState, что действительно отвечает на ваши сомнения.

React keeps track of the currently rendering component. Thanks to the Rules of Hooks, we know that Hooks are only called from React components (or custom Hooks — which are also only called from React components).

There is an internal list of “memory cells” associated with each component. They’re just JavaScript objects where we can put some data. When you call a Hook like useState(), it reads the current cell (or initializes it during the first render), and then moves the pointer to the next one. This is how multiple useState() calls each get independent local state.

Я написал довольно хороший пример того, что вы можете сделать для более надежного хука useFetch в моем пакете использовать-http ?

Другие вопросы по теме