Как исправить отсутствующую зависимость в React Hook useEffect - PullRequest
18 голосов
/ 25 апреля 2019

С React 16.8.6 (предыдущая версия была хороша для 16.8.3), я получаю эту ошибку, когда пытаюсь предотвратить бесконечный цикл в запросе на выборку

./src/components/BusinessesList.js
Line 51:  React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array  react-hooks/exhaustive-deps

Я не смогнайти решение, которое хорошо остановит бесконечный цикл.Я хочу держаться подальше от использования useReducer().Я нашел это обсуждение https://github.com/facebook/react/issues/14920, где возможное решение - You can always // eslint-disable-next-line react-hooks/exhaustive-deps if you think you know what you're doing. Я не уверен в том, что я делаю, поэтому я еще не пытался его реализовать.

У меня есть текущая настройка React hook useEffect выполняется постоянно навсегда / бесконечный цикл , и единственный комментарий касается useCallback(), с которым я не знаком.

Как я сейчас использую useEffect() (который я хочу запустить только один раз в начале, аналогично componentDidMount())

useEffect(() => {
    fetchBusinesses();
  }, []);
const fetchBusinesses = () => {
    return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };

Ответы [ 6 ]

17 голосов
/ 25 апреля 2019

Если вы не используете метод fetchBususiness где-либо кроме эффекта, вы можете просто переместить его в эффект и избежать предупреждения

useEffect(() => {
    const fetchBusinesses = () => {
       return fetch("theURL", {method: "GET"}
    )
      .then(res => normalizeResponseErrors(res))
      .then(res => {
        return res.json();
      })
      .then(rcvdBusinesses => {
        // some stuff
      })
      .catch(err => {
        // some error handling
      });
  };
  fetchBusinesses();
}, []);

Если вы используете fetchBususiness за пределами рендера, вы должны отметить две вещи

  1. Если есть какая-либо проблема, если вы не передадите fetchBusinesses как метод и что она используется во время монтирования с закрывающим закрытием, проблем не будет.
  2. Зависит ли ваш метод от некоторых переменных, которые он получает из закрытого замыкания, что не относится к вам.
  3. При каждом рендеринге fetchBususiness будет воссоздан, и, следовательно, передача его в useEffect вызовет проблемы. Поэтому сначала вы должны запомнить fetchBususiness, если вам нужно было передать его в массив зависимостей.

Подводя итог, я бы сказал, что если вы используете fetchBusinesses за пределами useEffect, вы можете отключить правило, используя // eslint-disable-next-line react-hooks/exhaustive-deps, в противном случае вы можете переместить метод внутрь useEffect

Чтобы отключить правило, вы должны написать его как

useEffect(() => {
   // other code
   ...

   // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) 
4 голосов
/ 25 апреля 2019
./src/components/BusinessesList.js
Line 51:  React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array  react-hooks/exhaustive-deps

Это не ошибка JS / React, а скорее предупреждение об ошибке.

Это говорит вам, что ловушка зависит от функции fetchBusinesses, поэтому вы должны передать ее как зависимость.

useEffect(() => {
  fetchBusinesses();
}, [fetchBusinesses]);

Это ничего не изменит, если fetchBusinessess не будет запущен, но предупреждение исчезнет.

Подробнее: https://github.com/facebook/react/issues/14920

2 голосов
/ 25 апреля 2019

Эта статья является хорошим учебником по извлечению данных с помощью хуков: https://www.robinwieruch.de/react-hooks-fetch-data/

По сути, включите определение функции извлечения внутри useEffect:

useEffect(() => {
  const fetchBusinesses = () => {
    return fetch("theUrl"...
      // ...your fetch implementation
    );
  }

  fetchBusinesses();
}, []);
1 голос
/ 23 июня 2019

Решение также дается реакцией, они советуют вам использовать useCallback, который возвратит версию вашей функции в памятку:

Функция 'fetchBususiness' создает зависимости useEffect Hook (встрока NN) изменить на каждом рендере.Чтобы исправить это, оберните определение 'fetchBususiness' в его собственное useCallback (). Hook реагировать-крючки / исчерпывающее-deps

useCallback прост в использовании, так как имеет такую ​​же подпись, как useEffectРазница в том, что useCallback возвращает функцию.Это будет выглядеть так:

 const fetchBusinesses = useCallback( () => {
        return fetch("theURL", {method: "GET"}
    )
    .then(// some stuff)
    .catch(// some error handling)
  }, [//deps])
  // We have a first effect thant uses fetchBusinesses
  useEffect(() => {
    // do things and then fetchBusinesses
    fetchBusinesses(); 
  }, [fetchBusinesses]);
   // We can have many effect thant uses fetchBusinesses
  useEffect(() => {
    // do other things and then fetchBusinesses
    fetchBusinesses();
  }, [fetchBusinesses]);
0 голосов
/ 05 июня 2019

Вы можете удалить массив 2-го типа аргумента [], но fetchBusinesses() также будет вызываться при каждом обновлении.Вы можете добавить оператор IF в реализацию fetchBusinesses(), если хотите.

React.useEffect(() => {
  fetchBusinesses();
});

Другой вариант - реализовать функцию fetchBusinesses() вне компонента.Только не забудьте передать любые аргументы зависимости вашему вызову fetchBusinesses(dependency), если он есть.

function fetchBusinesses (fetch) {
  return fetch("theURL", { method: "GET" })
    .then(res => normalizeResponseErrors(res))
    .then(res => res.json())
    .then(rcvdBusinesses => {
      // some stuff
    })
    .catch(err => {
      // some error handling
    });
}

function YourComponent (props) {
  const { fetch } = props;

  React.useEffect(() => {
    fetchBusinesses(fetch);
  }, [fetch]);

  // ...
}
0 голосов
/ 22 мая 2019

просто отключите eslint для следующей строки;

useEffect(() => {
   fetchBusinesses();
// eslint-disable-next-line
}, [fetchBusinesses]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...