React Hooks Dependencies - Бесконечный цикл - PullRequest
0 голосов
/ 31 мая 2019

У меня есть следующий код:

import React from "react";

export const useFetch = (promise, args = [], options = {}) => {
  const [state, setState] = React.useState({
    loading: false,
    data: null,
    error: null
  });

  if (!args) args = [];

  const fetch = React.useCallback((...args) => {
    setState({
      ...state,
      loading: true,
      error: null
    });

    return promise(...args)
      .then(response => {
        setState({
          ...state,
          loading: false,
          data: response
        });
        return response;
      })
      .catch(error => {
        setState({
          ...state,
          loading: false,
          error
        });
      });
  }, [promise, state]);

  React.useEffect(() => {
    if (options.now) {
      fetch(...args);
    }
  }, [args, fetch, options.now]);

  return {
    fetch,
    ...state
  };
};

Но Я получаю бесконечный цикл console.log , когда пытаюсь использовать вот так:

const allUsers = () => Promise.resolve([{ name: 'Bruno' }])

function App() {
  const { data } = useFetch(allUsers, [], { now: true })
  console.log('->', data)
  return (
    <span>Testing hook</span>
  )
}

Все deps и useCallback были предложениями от lint Reaction-hooks / исчерпывающе-deps. Итак, что я делаю не так?

Спасибо за вашу помощь.

1 Ответ

1 голос
/ 31 мая 2019

Есть 2 проблемы. 1. Ваша выборка получает новое значение каждый раз, так как она имеет состояние в качестве зависимости, и это вызывает запуск useEffect каждый раз, так что бесконечный цикл. 2.useEffect имеет аргументы в качестве зависимости, которая также не всегда одинакова, вам не нужно передавать аргументы для извлечения, поскольку она уже доступна из-за закрытия.

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

const useFetch = (promise, args = [], options = {}) => {
  const [state, setState] = React.useState({
    loading: false,
    data: null,
    error: null
  });

  if (!args) args = [];

  const fetch = React.useCallback(() => {
    setState({
      ...state,
      loading: true,
      error: null
    });

    return promise(...args)
      .then(response => {
        setState({
          ...state,
          loading: false,
          data: response
        });
        return response;
      })
      .catch(error => {
        setState({
          ...state,
          loading: false,
          error
        });
      });
  }, [promise]);

  React.useEffect(() => {
    if (options.now) {
      fetch();
    }
  }, [fetch, options.now]);

  return {
    fetch,
    ...state
  };
};

const allUsers = () => Promise.resolve([{ name: 'Bruno' }])


const App = props => {
  const { data } = useFetch(allUsers, [], { now: true });
  console.log(data, "=>");
  return <input name="name" onChange={this.handleInputChange} />;
}
...