Как исправить отсутствующее предупреждение о зависимости при использовании useEffect React Hook

С 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(). Я нашел это обсуждение [ESLint] Отзыв о правиле lint 'exhaustive-deps' #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
      });
  };

Поскольку этот вопрос получает много трафика, вот ссылка на Блог Дэна Абрамова, где он подробно объясняет useEffect и его зависимости.

chetan 28.02.2021 13:05

И запрос функции, чтобы React улучшили useEffect API, чтобы избежать этой проблемы, четко отделив триггеры эффектов от зависимостей эффектов: github.com/facebook/реагировать/вопросы/22132 Поскольку Next.js включил линтинг по умолчанию, это предупреждение должно появляться миллион раз в день во всем мире, это должно прекратиться. как-то.

Eric Burel 24.11.2021 13:59

Согласитесь, это совершенно неясно из официальной документации. Такая библиотека, как React, не нуждается в форумах и сообщениях в блогах, чтобы заставить ее работать.

Kokodoko 08.12.2021 17:50
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
604
3
638 861
19
Перейти к ответу Данный вопрос помечен как решенный

Ответы 19

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

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

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

  fetchBusinesses();
}, []);
./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

Это не ошибка JavaScript/React, а предупреждение ESLint (eslint-plugin-react-hooks).

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

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

Это может привести к вызову функции при каждом рендеринге, если функция объявлена ​​в компоненте, например:

const Component = () => {
  /*...*/

  // New function declaration every render
  const fetchBusinesses = () => {
    fetch('/api/businesses/')
      .then(...)
  }

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

  /*...*/
}

потому что каждый раз функция переопределяется с новой ссылкой.

Правильный способ сделать это:

const Component = () => {
  /*...*/

  // Keep the function reference
  const fetchBusinesses = useCallback(() => {
    fetch('/api/businesses/')
      .then(...)
  }, [/* Additional dependencies */])

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

  /*...*/
}

Или просто определите функцию в useEffect.

Подробнее: [ESLint] Отзыв о правиле lint 'exhaustive-deps' #14920

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

cesarlarsson 09.01.2020 20:12
Ответ принят как подходящий

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

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();
}, []);

Однако, если вы используете fetchBusinesses вне рендеринга, вы должны обратить внимание на две вещи.

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

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

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

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

   // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) 

Я использовал решение, которое вы хорошо изложили. Еще одно решение, которое я использовал в другом месте из-за другой настройки, было useCallback(). Так, например: const fetchBusinesses= useCallback(() => { ... }, [...]) и useEffect() будет выглядеть так: useEffect(() => { fetchBusinesses(); }, [fetchBusinesses]);

russ 26.04.2019 00:39

@russ, вы правы, вам нужно будет запомнить fetchBusiness с помощью useCallback, если вы хотите передать его в массив зависимостей

Shubham Khatri 26.04.2019 07:41

Было бы неплохо, если бы вы показали, куда поставить оператор eslint-disable. Я думал, что это будет выше useEffect

user210757 18.06.2019 23:30

использование // eslint-disable-next-line react-hooks/exhaustive-deps для объяснения линтеру, что ваш код правильный, похоже на взлом. Я ожидаю, что они найдут другое решение, чтобы сделать линтер достаточно умным, чтобы определять, когда аргумент не является обязательным.

Olivier Boissé 27.10.2019 12:59

Как насчет асинхронной функции?

Tapas Adhikary 20.11.2019 06:08

@TapasAdhikary, асинхронную функцию также можно вызвать из useEffect

Shubham Khatri 20.11.2019 06:10

Спасибо @ShubhamKhatri, я понял. Мой вопрос заключался в том, что если мы хотим использовать само определение функции внутри useEffect(), а моя функция является ансинхронной функцией, которая была вне useEffect(), как получить это внутри? Функция aync получила ключевое слово await, которое, я полагаю, не может быть размещено как есть.

Tapas Adhikary 20.11.2019 06:18

@TapasAdhikary, да, у вас может быть асинхронная функция в useEffect, вам просто нужно написать ее по-другому. Пожалуйста, проверьте stackoverflow.com/questions/53332321/…

Shubham Khatri 20.11.2019 06:19

«Если есть какие-либо проблемы, если вы не передадите fetchBusinesses как метод и что он используется во время монтирования с его закрывающим закрытием, не будет никаких проблем». -> Это предложение неясно.

Giorgi Moniava 23.12.2019 11:07

Я могу предвидеть, что во многих проектах везде будет много кода, где будет писаться эта строка отключения. Я чувствую, что это ошибка, которую нужно решить разработчикам.

Fiddle Freak 19.08.2020 15:52

Но это не работает, когда мы используем async и await внутри функции useEffect. Поэтому я попытался поставить его снаружи. Но это все еще не работает!

Akhila 11.10.2020 22:55

Я думаю, что принятым ответом должен быть ответ на «r g» ниже. ИМО - плохая практика комментировать ошибки ворса, когда есть другое жизнеспособное решение. + вам нужно доверять следующему разработчику, который редактирует этот код, чтобы сначала удалить комментарий.

Erez Cohen 02.11.2020 11:09

Я ненавижу это, когда приходится перемещать функцию внутри хука. Должен быть лучший способ.

Robert Moskal 16.11.2020 16:17

линтер все еще тупой сегодня, и если вы хотите поведение, подобное componentDidMount, при использовании внешних переменных (необходимо, чтобы некоторые, но не все из них вызывали повторную визуализацию в случае их изменения), вы получите это предупреждение независимо от того, что вы делаете.... в по крайней мере, я не смог найти решение в Интернете

rayaqin 09.04.2021 16:01

@rayaqin Do может отключить линтер для этой строки, если вы абсолютно уверены, что делаете правильно.

Shubham Khatri 09.04.2021 18:03

это не заставит предупреждение браузера исчезнуть, только предупреждение в IDE

rayaqin 11.04.2021 10:03

Привет, ребята, я отправил запрос функции для дополнительного параметра «триггеры» в useEffect, чтобы различать зависимости, которые должны запускать повторный запуск эффекта, и зависимости, которые просто запускают обновление обратного вызова эффекта, но не запускают его. Я хотел бы получить отзыв об этом: github.com/facebook/реагировать/вопросы/22132 (связанная песочница кода: codeandbox.io/s/fancy-sea-zj5e4).

Eric Burel 19.08.2021 10:42

И люди удивляются, почему мы, «ленивые» разработчики, склонны игнорировать предупреждения, лол.

Chev 01.10.2021 18:22

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

useEffect(() => {
   fetchBusinesses();
// eslint-disable-next-line
}, []);

Таким образом, вы используете его так же, как компонент, который монтируется (вызывается один раз).

обновлен

или

const fetchBusinesses = useCallback(() => {
 // Your logic in here
 }, [someDeps])

useEffect(() => {
   fetchBusinesses();
// No need to skip the ESLint warning
}, [fetchBusinesses]);

fetchBusinesses будет вызываться каждый раз при изменении некоторые Депсы.

вместо отключения просто сделайте следующее: [fetchBusinesses] автоматически удалит предупреждение, и это решило проблему для меня.

rotimi-best 03.06.2019 09:33

@RotimiBest - это приводит к бесконечному повторному рендерингу, как описано в вопросе.

user210757 18.06.2019 23:43

На самом деле я сделал это в одном из своих проектов некоторое время назад, и это не привело к бесконечному циклу. Я проверю еще раз, хотя.

rotimi-best 19.06.2019 12:35

@ user210757 Подождите, но почему это вызовет бесконечный цикл, ведь вы не устанавливаете состояние после получения данных с сервера. Если вы обновляли состояние, просто напишите условие if перед вызовом функции в useEffect, которая проверяет, пусто ли состояние.

rotimi-best 25.01.2020 06:51

@rotimi-best был ahwile с тех пор, как я прокомментировал, но я бы сказал, что функция воссоздается каждый раз, поэтому никогда не бывает одинаковой, поэтому всегда будет перерисовываться, если вы не перейдете в тело useEffect или useCallback

user210757 26.01.2020 19:34

см. это полезное обсуждение: github.com/facebook/создать-реагировать-приложение/issues/6880

Joe 29.01.2020 13:42

Что вы подразумеваете под "точно так же, как компонент монтировался" (кажется непонятным)? Пожалуйста, ответьте с помощью редактирование (изменение) вашего ответа, а не здесь, в комментариях (без "Редактировать:", "Обновить:" или подобное - ответ должен выглядеть так, как будто он был написан сегодня).

Peter Mortensen 15.07.2021 11:16

Вы можете удалить второй массив типов аргументов [], но 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]);

  // ...
}

удаление скобок массива зависимостей вызвало проблему бесконечного повторного рендеринга в компоненте, где у меня есть форма!

Harvester Haidar 25.06.2021 04:04

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

The 'fetchBusinesses' function makes the dependencies of the useEffect Hook (at line NN) change on every render. To fix this, wrap the 'fetchBusinesses' definition into its own useCallback() Hook react-hooks/exhaustive-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 that uses fetchBusinesses
  useEffect(() => {
    // Do things and then fetchBusinesses
    fetchBusinesses();
  }, [fetchBusinesses]);
   // We can have many effects that use fetchBusinesses
  useEffect(() => {
    // Do other things and then fetchBusinesses
    fetchBusinesses();
  }, [fetchBusinesses]);

В моем случае этот крючок useCallBack решил мою проблему. Подробности см. на странице документация.

khan 08.09.2021 20:36

Редактировать 20.09.2021

There are very good options for state management libs if you are creating a new app or have enough flexibility. Check out Recoil.

Просто для полноты:

1. (Перестал работать) Использовать функцию как обратный вызов useEffect

useEffect(fetchBusinesses, [])

2. Объявить функцию внутри useEffect()

useEffect(() => {
  function fetchBusinesses() {
    ...
  }
  fetchBusinesses()
}, [])

3. Запоминай с useCallback()

В этом случае, если у вас есть зависимости в вашей функции, вам придется включить их в массив зависимостей useCallback, и это снова вызовет useEffect, если параметры функции изменятся. Кроме того, это много шаблонного... Так что просто передайте функцию прямо в useEffect, как в 1. useEffect(fetchBusinesses, []).

const fetchBusinesses = useCallback(() => {
  ...
}, [])
useEffect(() => {
  fetchBusinesses()
}, [fetchBusinesses])

4. Аргумент функции по умолчанию

As suggested by https://stackoverflow.com/a/61183162/5552686

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

5. Создайте собственный хук

Создайте собственный хук и вызывайте его, когда вам нужно запустить функцию только один раз. Может быть чище. Вы также можете вернуть обратный вызов для сброса повторного запуска «инициализации», когда это необходимо.

// customHooks.js
const useInit = (callback, ...args) => {
  const [mounted, setMounted] = useState(false)
  
  const resetInit = () => setMounted(false)

  useEffect(() => {
     if (!mounted) {
        setMounted(true);
        callback(...args);
     }
  },[mounted, callback]);

  return [resetInit]
}

// Component.js
return ({ fetchBusiness, arg1, arg2, requiresRefetch }) => {
  const [resetInit] = useInit(fetchBusiness, arg1, arg2)

  useEffect(() => {
    resetInit()
  }, [requiresRefetch, resetInit]);

6. Отключить предупреждение eslint

Disabling warnings should be your last resort, but when you do, better do it inline and explicitly, because future developers may be confused or create unexpected bugs without knowing linting is off

useEffect(() => {
  fetchBusinesses()
}, []) // eslint-disable-line react-hooks/exhaustive-deps

Исходный ответ

Вы можете установить его непосредственно как обратный вызов useEffect:

useEffect(fetchBusinesses, [])

Он сработает только один раз, поэтому убедитесь, что все зависимости функции установлены правильно (так же, как при использовании componentDidMount/componentWillMount...).

Можно ли отключить предупреждение эслинта?

Rohan Shenoy 02.09.2020 15:48

Я предпочитаю отключать предупреждения в крайнем случае, потому что будущие разработчики могут запутаться или создать неожиданные ошибки, не зная, что линтинг отключен.

jpenna 02.09.2020 20:12

В последней реакции. Если я объявляю состояние, а компонент использует useEffect, отображается предупреждение. Таким образом, в этом случае решения 1, 2 и 3 неприменимы, так как я хочу, чтобы они запускались только один раз. Что я должен делать?

Rohan Shenoy 03.09.2020 06:32

@RohanShenoy Если я правильно понимаю, вы хотите использовать состояние внутри useEffect, это совершенно другая ситуация. В этом случае вы можете только отключить предупреждение, потому что теперь у вас есть вторая внешняя зависимость

jpenna 04.09.2020 17:36
useEffect(fetchBusinesses, []) выдаст «Ошибка типа: функция эффекта не должна возвращать ничего, кроме функции, которая используется для очистки»., так как fetchBusinesses возвращает обещание.
Emile Bergeron 16.12.2020 20:49

@EmileBergeron Это правда с реализацией OP! Они могли бы просто удалить return из fetchBusinesses, так как это не требуется.

jpenna 17.12.2020 02:44

@EmileBergeron useEffect не следует передавать асинхронной функции, это можно сделать следующим образом: useEffect( () => { asyncFunc() } ,[])

Shani Kehati 11.02.2021 11:49
// eslint-disable-line react-hooks/exhaustive-deps работает как шарм.
Lane 20.02.2021 10:19

Первое предложение на удивление не устраняет предупреждение

ericjam 31.03.2021 16:42

Это БОЛЬШЕ НЕ РАБОТАЕТ!!!!

CrazyDev 19.09.2021 22:35

Есть ли разница, если функция асинхронная? Это то, что я делаю, это правильно? const loadAgents = useCallback(async ()=> { try { ... const response = await axios.post(...); setAgentsData(response.data); } catch (e) { ... } finally { .. . } }, []); useEffect(() => { if (...) loadAgents(); }, [uiState.selectedSwitch, loadAgents]);

Daniel Tkach 08.10.2021 19:29

Обратите внимание, я должен был поставить // eslint-disable-next-line react-hooks/exhaustive-deps, а не // eslint-disable-line react-hooks/exhaustive-deps

Lewy Blue 26.12.2021 00:58

@LewyBlue это потому, что вы добавили комментарий над в строку зависимостей

jpenna 27.12.2021 13:46

Эти предупреждения очень полезны для поиска компонентов, которые не обновляются последовательно: Безопасно ли исключать функции из списка зависимостей?.

Однако, если вы хотите удалить предупреждения по всему проекту, вы можете добавить это в свою конфигурацию ESLint:

  {
  "plugins": ["react-hooks"],
  "rules": {
    "react-hooks/exhaustive-deps": 0
    }
  }

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

Если вы не хотите помещать fetchBusinesses в зависимости хука, вы можете просто передать его в качестве аргумента обратному вызову хука и установить основной fetchBusinesses в качестве значения по умолчанию для него следующим образом:

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

Это не лучшая практика, но в некоторых случаях это может быть полезно.

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

// eslint-disable-next-line react-hooks/exhaustive-deps
const [mount, setMount] = useState(false)
const fetchBusinesses = () => {
   // Function definition
}
useEffect(() => {
   if (!mount) {
      setMount(true);
      fetchBusinesses();
   }
},[fetchBusinesses, mount]);

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

И вы будете делать это каждый раз, когда вам понадобится componentDidMount?

Zhivko Zhelev 14.12.2020 11:29

Затем это пометит вас, что вам нужно добавить mount в качестве зависимости от useEffect.

Preston 15.09.2021 22:40

Вы попробуйте так:

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
        });
  };

а также

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

Это работает для вас.

Но я предлагаю попробовать этот способ, и он также работает для вас. Это лучше, чем предыдущий способ. Я использую это следующим образом:

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();
}, []);

Если вы получаете данные на базе определенного id, то добавьте в callback useEffect [id]. Тогда он не может показать вам предупреждение React Hook useEffect has a missing dependency: 'any thing'. Either include it or remove the dependency array

Просто передайте функцию в качестве аргумента в массиве useEffect...

useEffect(() => {
   functionName()
}, [functionName])

Что ж, если вы хотите посмотреть на это по-другому, вам просто нужно знать, какие опции есть у React, которые не являются exhaustive-deps. Одна из причин, по которой вы не должны использовать функцию замыкания внутри эффекта, заключается в том, что при каждом рендеринге он будет воссоздаваться/уничтожаться снова.

Таким образом, в хуках есть несколько методов React, которые считаются стабильными и неисчерпаемыми, где вам не нужно применять зависимости useEffect и, в свою очередь, не будет нарушать правила взаимодействия react-hooks/exhaustive-deps. Например, вторая возвращаемая переменная useReducer или useState, которая является функцией.

const [,dispatch] = useReducer(reducer, {});

useEffect(() => {
    dispatch(); // Non-exhausted - ESLint won't nag about this
}, []);

Так что, в свою очередь, вы можете сосуществовать со всеми вашими внешними зависимостями с вашими текущими зависимостями в вашей функции редуктора.

const [,dispatch] = useReducer((current, update) => {
    const { foobar } = update;
    // Logic

    return { ...current, ...update };
}), {});

const [foobar, setFoobar] = useState(false);

useEffect(() => {
    dispatch({ foobar }); // non-exhausted `dispatch` function
}, [foobar]);

Это предупреждение возникает, если переменные, которые вы используете внутри useEffect, определены внутри компонента или переданы компоненту в качестве реквизита. Поскольку вы определили fetchBusinesses() внутри того же компонента, вы должны передать его в массив зависимостей.

Но если вы импортировали fetchBusinesses(), а затем использовали его внутри useEffect, вам не нужно было бы добавлять его в массив зависимостей. Вот как мы на самом деле настраиваем наши приложения Редукс: мы всегда импортируем наших создателей действий и запускаем их внутри useEffect, не добавляя их в массив зависимостей.

То же самое верно и для useMemo.

вы все равно получите предупреждение, даже если импортируете функцию из своего магазина. Потому что ваши функции будут переданы объекту props через вызов mapDispatchToProps или с использованием второго аргумента тега connect. connect(mapStateToProps, {fetchBusinesses})(Component)

osmancakirio 24.08.2021 09:59

@osmancakirio Вы нашли решение предупреждения в этом случае? У меня та же проблема...

ndtreviv 28.10.2021 16:12

@ndtreviv Я провел рефакторинг компонентов, чтобы теперь вместо тега подключения использовались редукционные хуки. затем я передаю функцию отправки массиву зависимостей. Это также рекомендуется разработчиками redux, поскольку, как они говорят, это безопасно, потому что ссылка на функцию отправки почти никогда не меняется.

osmancakirio 03.11.2021 17:19

В моем случае это предупреждение было связано с моей локальной переменной organization, и когда я помещал organization в массив зависимостей, useEffect извлекался бесконечно. Поэтому, если у вас есть проблемы, подобные моей, используйте useEffect с массивом зависимостей и разделите:

Потому что, если у вас есть несколько вызовов API, которые изменяют состояние, он вызывает useEffect несколько раз.

От:

  const { organization } = useSelector(withOrganization)
  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(getOrganization({}))
    dispatch(getSettings({}))
    dispatch(getMembers({}))
  }, [dispatch, organization])

К:

  const { organization } = useSelector(withOrganization)
  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(getOrganization({}))
    dispatch(getSettings({}))
  }, [dispatch, organization])

  useEffect(() => {
    dispatch(getMembers({}))
  }, [dispatch])

Вы можете избавиться от этого предупреждения Es-lint, передав ссылку на него:

Пример указан ниже, однако вы можете посмотреть решение по этой ссылке: https://thewikihow.com/video_r4A46oBIwZk&t=8s

Предупреждение: Строка 13:8: React Hook В React.useEffect отсутствуют зависимости: «история» и «currentUser?.role». Либо включите их, либо удалите массив зависимостей react-hooks/exhaustive-deps

React.useEffect(() => {
    if (currentUser?.role !== "Student") {
        return history.push("/")
    }
}, [])

Разрешение: Шаг 1: Переместите бизнес-логику в отдельный const.

Теперь предупреждение: React Hook React.useEffect имеет недостающую зависимость: «roleChecking».

const roleChecking = () =>{
   if (currentUser?.role !== "Student") {
        return history.push("/")
    }
}

React.useEffect(() => {
    roleChecking()
}, [])

Последний шаг — создать ссылку на функцию:

  const roleRef = React.useRef();

  const roleChecking = () => {
    if (currentUser?.role !== "Student") {
      return history.push("/");
    }
  };
  roleRef.current = roleChecking;

  React.useEffect(() => {
   return roleRef.current();
  }, [currentUser?.role]);

Кажется, функция fetchBusinesses объявлена ​​в компоненте. Это означает, что в каждом рендере объявляется новая функция, которая запускает хук.

Есть 2 подхода к решению проблемы.

  1. Переместите объявление функции fetchBusinesses из компонента.

  2. Оберните функцию fetchBusinesses крючком useCallback.

Первый вариант предпочтительнее.

Это не ответ, специфичный для варианта использования вопроса, а более общий случай, и он охватывает случай, когда useEffect или извлечение и импорт не работают. Сценарий useRef:

Иногда сценарий заключается в том, что useEffect должен иметь пустой массив, и вы все еще хотите использовать его внутри частей состояния useEffect, но все же вы не хотите вводить их в качестве зависимостей, также вы можете попробовать использовать useCallback, и теперь реакция жалуется на зависимости использования Callback и вы застряли. При этом в некоторых случаях можно использовать useRef. Например:

const locationRef = useRef(location);
useEffect(()=>{
const qs = locationRef.current.search
...
},[])

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

используя функцию вызова UseEffect fetchBusinesses, объявите в useEffect(), объявив константную переменную после вызова имени функции,

useEffect(()=>{
const fetchBusinesses=()=>{
   console.info(useeffect fetchbussinesses functions)
}
 fetchBusinesses();
},[declare the variable used in useeffect hooks ])

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