В 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 ловушка 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
});
};
useCallback()
. Так, например:const fetchBusinesses= useCallback(() => { ... }, [...])
иuseEffect()
будет выглядеть так:useEffect(() => { fetchBusinesses(); }, [fetchBusinesses]);
// eslint-disable-next-line react-hooks/exhaustive-deps
для объяснения линтеру, что ваш код правильный, как хак. Я ожидаю, что они найдут другое решение, чтобы сделать линтер достаточно умным, чтобы обнаружить, когда аргумент не является обязательнымЭто не ошибка JS / React, а предупреждение eslint (eslint-plugin-response-hooks).
Он говорит вам, что ловушка зависит от функции
fetchBusinesses
, поэтому вы должны передать ее как зависимость.Это может привести к вызову функции при каждом рендеринге, если функция объявлена в компоненте, например:
потому что каждый раз функция повторно объявлена с новой ссылкой
Правильный способ сделать это:
или просто определяя функцию в
useEffect
Подробнее: https://github.com/facebook/react/issues/14920
источник
Line 20: The 'fetchBusinesses' function makes the dependencies of useEffect Hook (at line 51) change on every render. Move it inside the useEffect callback. Alternatively, wrap the 'fetchBusinesses' definition into its own useCallback() Hook
Вы можете установить это непосредственно как
useEffect
обратный вызов:Он сработает только один раз, поэтому убедитесь, что все зависимости функции установлены правильно (так же, как и при использовании
componentDidMount/componentWillMount...
)Изменить 21.02.2020
Просто для полноты:
1. Используйте функцию в качестве
useEffect
обратного вызова (как указано выше)2. Объявить функцию внутри
useEffect()
3. Поминать с
useCallback()
В этом случае, если у вас есть зависимости в вашей функции, вам придется включить их в
useCallback
массив зависимостей, и это вызоветuseEffect
снова, если параметры функции изменятся. Кроме того, это много шаблонного ... Так что просто передайте функцию напрямую,useEffect
как в1. useEffect(fetchBusinesses, [])
.4. Отключить предупреждение Эслинта
источник
Решение также дается реакцией, они советуют вам использовать,
useCallback
что вернет запоминающуюся версию вашей функции:useCallback
Он прост в использовании, поскольку имеет ту же сигнатуру, чтоuseEffect
и различие в том, что useCallback возвращает функцию. Это будет выглядеть так:источник
Эти предупреждения очень полезны для поиска компонентов, которые не обновляются последовательно: https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of- зависимости .
Однако, если вы хотите удалить предупреждения во всем проекте, вы можете добавить это в конфигурацию eslint:
источник
Эта статья является хорошим учебником по извлечению данных с помощью хуков: https://www.robinwieruch.de/react-hooks-fetch-data/
По сути, включите определение функции извлечения внутри
useEffect
:источник
Вы можете удалить массив 2-го типа аргумента,
[]
ноfetchBusinesses()
он также будет вызываться при каждом обновлении. Вы можете добавитьIF
заявление вfetchBusinesses()
реализацию, если хотите.Другой - реализовать
fetchBusinesses()
функцию за пределами вашего компонента. Только не забудьте передать любые аргументы зависимости на вашfetchBusinesses(dependency)
вызов, если таковые имеются.источник
На самом деле предупреждения очень полезны, когда вы разрабатываете с помощью хуков. но в некоторых случаях это может вас уколоть. особенно когда вам не нужно прислушиваться к изменению зависимостей.
Если вы не хотите помещать
fetchBusinesses
в зависимости хука, вы можете просто передать его в качестве аргумента обратному вызову хука и установитьfetchBusinesses
для него значение main по умолчанию, например:Это не лучшая практика, но она может быть полезна в некоторых случаях.
Также, как писал Шубнам, вы можете добавить код ниже, чтобы ESLint игнорировал проверку вашего хука.
источник
Вы можете
fetchBusinesses
полностью вытащить свой компонент:Это не только предоставит простое решение и решит проблему исчерпывающего предупреждения.
fetchBusiness
теперь может быть проверен лучше и облегчаетComp
, поскольку он находится в области видимости модуля вне дерева React.Перемещение
fetchBusinesses
за пределы хорошо работает здесь, так как мы будем в состоянии только прочитать начальные реквизиты и состояние из компонента в любом случае из-за устаревшей области закрытия ([]
dep inuseEffect
).Как опустить зависимости функций
useEffect
зависит от этого значения (чисто вычислительная функция)useCallback
как последнее средствоПо поводу других решений:
Вытягивание
fetchBusinesses
изнутриuseEffect()
не очень помогает, если вы получаете доступ к другому состоянию в нем. Эслинт все равно будет жаловаться Codesandbox .Я также держался бы в стороне от исчерпывающего eslint-deps игнорировать комментарии. Просто их легко забыть, когда вы проводите рефакторинг и капитальный ремонт ваших зависимостей.
источник
Это решение довольно простое, и вам не нужно переопределять предупреждения es-lint. Просто установите флажок, чтобы проверить, смонтирован ли компонент или нет.
источник
ты попробуй так
и
это работа для вас. Но я предлагаю попробовать этот способ и работать на вас. Это лучше, чем раньше. Я использую этот способ:
если вы получаете данные на основе определенного идентификатора, а затем добавьте в функцию обратного вызова useEffect,
[id]
то вы не сможете отобразить предупреждениеReact Hook useEffect has a missing dependency: 'any thing'. Either include it or remove the dependency array
источник
просто отключите eslint для следующей строки;
таким образом, вы используете его так же, как компонент монтировал (вызывается один раз)
обновленный
или
fetchBususiness будет вызываться каждый раз, когда некоторые изменения будут меняться
источник
[fetchBusinesses]
автоматически удалит предупреждение, и это решило проблему для меня.useEffect
которая проверяет, является ли состояние пустым.