Найти в Дзене
Bereshpolov

Как исправить бесконечный цикл внутри «useEffect» (React Hooks)

Если вы начнете использовать React-Hooks, вашему компоненту в какой-то момент может понадобиться метод жизненного цикла. И вот тогда вы начнете использовать useEffect() (он же Effect Hook). И тут — бум! Вы столкнулись с поведением бесконечного цикла и понятия не имеете, почему, черт возьми, это происходит. Если это произойдет, эта статья объяснит, почему и как это можно предотвратить. Приведенный ниже фрагмент кода является примером использования Effect Hook, но он имеет поведение бесконечного цикла. Что делает этот код? В чем проблема? «useEffect()» запустится после первоначального рендеринга, а затем вызовет «fetchUser()». Внутри «fetchUser» он обновит состояние «name» в строке 9. Затем он снова запустит компонент для повторного рендеринга. В результате «useEffect()» снова запустится и обновит состояние. Затем весь процесс повторяется снова, и вы оказываетесь в ловушке бесконечного цикла. «Вы можете указать React пропустить применение эффекта, если определенные значения не изменились
Оглавление

Если вы начнете использовать React-Hooks, вашему компоненту в какой-то момент может понадобиться метод жизненного цикла. И вот тогда вы начнете использовать useEffect() (он же Effect Hook). И тут — бум! Вы столкнулись с поведением бесконечного цикла и понятия не имеете, почему, черт возьми, это происходит. Если это произойдет, эта статья объяснит, почему и как это можно предотвратить.

Пример использования Effect Hook

Приведенный ниже фрагмент кода является примером использования Effect Hook, но он имеет поведение бесконечного цикла.

-2

Что делает этот код?

  • Вкратце, компонент «DisplayName» имеет два состояния: «name» и «userId».
  • И у него есть функция «fetchUser()», которая обрабатывает извлечение данных из API и установку «name».
  • Затем есть «useEffect()», которая вызовет «fetchUser()» после рендеринга элемента DOM.

В чем проблема?

«useEffect()» запустится после первоначального рендеринга, а затем вызовет «fetchUser()».

Внутри «fetchUser» он обновит состояние «name» в строке 9. Затем он снова запустит компонент для повторного рендеринга.

В результате «useEffect()» снова запустится и обновит состояние. Затем весь процесс повторяется снова, и вы оказываетесь в ловушке бесконечного цикла.

-3

Исправление бесконечного обновления

-4

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

В приведенном выше фрагменте теперь у нас есть необязательный второй аргумент [userId], переданный в «useEffect()».

Указывая [userId] в качестве второго аргумента, мы просто говорим «useEffect()» запускаться только в том случае, если определенное значение (userId) изменилось между повторными рендерингами компонента.

Ниже я привел схему для простоты.

-5

И вот, мы и сбежали из бесконечного мира!