Крюк Custom use React `useFetch` - нужно ли поддерживать несколько состояний? - PullRequest
0 голосов
/ 19 ноября 2018

Я реализовал пользовательский 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-й пример - это все, что мне нужно?

Ответы [ 2 ]

0 голосов
/ 02 мая 2019

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

0 голосов
/ 20 ноября 2018

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

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

Так чтоПервый пример будет работать как раз.

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

React отслеживает текущий компонент рендеринга.Благодаря правилам хуков мы знаем, что хуки вызываются только из компонентов React (или пользовательских хуков, которые также вызываются только из компонентов React).

Существует внутренний список «ячеек памяти», связанных скаждый компонент.Это просто объекты JavaScript, куда мы можем поместить некоторые данные.Когда вы вызываете Hook, например, useState (), он читает текущую ячейку (или инициализирует ее во время первого рендеринга), а затем перемещает указатель на следующий.Вот как несколько вызовов useState () получают независимое локальное состояние.

...