Функции React useEffect продолжают зацикливаться

у меня есть этот код

// snackbar.js
import { isString } from 'lodash';
import { useCallback, useMemo, useState } from 'react';
import toast from 'react-hot-toast';

const useSnackBar = () => {
  const [keys, setKeys] = useState([]);

  const closeSnackbar = useCallback(() => {
    toast.remove();
  }, []);

  const toastLoading = useCallback(message => {
    const key = toast.loading(message, { duration: 0 });

    setKeys(current => [...current, key]);
  }, []);

  const toastSuccess = useCallback(message => {
    toast.success(message);
  }, []);

  const toastInfo = useCallback(message => {
    toast(message);
  }, []);

  const toastError = useCallback(error => {
    if (error.response) {
      toast.error(error.response.data.message);
    } else if (isString(error)) {
      toast.error(error);
    } else {
      toast.error(
        'Something unexpected happened, we are investigating this issue right now',
      );
    }
  }, []);

  const displaySnackbar = useCallback((variant, data, options = {}) => {
    const closeLoading = () => {
      if (keys.length >= 1) {
        keys.map(() => closeSnackbar());
      }
    };
    closeSnackbar();

    switch (variant) {
      case 'error':
        toastError(data);
        break;
      case 'success':
        toastSuccess(data);
        break;
      case 'loading':
        toastLoading(data);
        break;
      case 'info':
        toastInfo(data);
        break;
      default:
        closeLoading();
    }
  }, []);

  return [displaySnackbar, closeSnackbar];
};


export default useSnackBar;

и использовать его так

// import and upper code

const [displaySnackbar, closeSnackbar] = useSnackbar();

useEffect(() => {
  if (loading.data) {
    displaySnackbar('loading', 'Searching batch disbursement data');
  }
}, [loading.data, displaySnackbar]);

// return components

если я удаляю displaySnackbar deps из useEffect, он работает отлично, но поскольку он должен быть deps (ошибка линтера), он продолжает зацикливаться при срабатывании.

Любое решение?

Обновлять:

https://codesandbox.io/s/red-resonance-m8h2vi

попробуйте удалить displaySnackbar из массива зависимостей и добавить eslint-disable-next-line над массивом зависимостей

Dharmik Patel 17.03.2022 06:53

@DharmikPatel определенно будет решен, если использовать отключенный eslint, но я хочу знать, какая часть моего кода неверна, что запускает циклы.

ssuhat 17.03.2022 06:55

Вы поделились полный и воспроизводимый пример кода? Я скопировал/вставил ваш код в работающий кодыпесочница и не могу воспроизвести проблему с зацикливанием рендеринга.

Drew Reese 17.03.2022 07:00

@DrewReese добавил codeandbox codeandbox.io/s/красный-резонанс-m8h2vi, как вы можете видеть в журнале, он будет выполнять бесконечный цикл

ssuhat 17.03.2022 07:07

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

Drew Reese 17.03.2022 07:17

Есть ли у вас версия вашего хука useSnackBar, который фактически запускает всплывающее уведомление без странного хука useEffect, ставящего в очередь обновления состояния?

Drew Reese 17.03.2022 07:29

@DrewReese реальный код, который он извлекает через API. и это просто простая проверка, загружается ли он или нет. поэтому я делаю песочницу такой

ssuhat 17.03.2022 08:18
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
7
46
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

  const toastLoading = useCallback((message) => {
    const key = toast.loading(message, { duration: 0 });
    if (message !== "Loading") {
      setKeys((current) => [...current, key]);
    }
  }, []);

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

ssuhat 17.03.2022 08:17

Вы видите «Максимальная глубина обновления превышена», когда обновляете свой код, как показано в примере? Кроме того, у вас нет break в случае переключателя по умолчанию.

semperlabs 17.03.2022 08:23

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

ssuhat 17.03.2022 08:27

конечно, нет проблем. счастливое кодирование

semperlabs 17.03.2022 08:28

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

Снимите флажок (удалив) последний элемент в флажке и одновременно отметьте (добавьте) другой, сохраните непроверенное значение и добавьте другое отмеченное значение
Использование отправки при событии изменения ввода вызывает повторную визуализацию всей страницы – Redux Toolkit
Я продолжаю получать сообщение об ошибке недопустимого вызова ловушки
Плохо или хорошо использовать Memo для запоминания и возврата отфильтрованного массива?
Как уменьшить количество состояний в React JS
Вызов rest должен возвращать данные как T, если не загружается и нет ошибок
Я хочу сначала загрузить первый элемент из API, но после внесения изменений в другие пользовательские данные компонент возвращается к данным первого элемента
DefaultValue реагирует на использование формы из объекта карты
Диаграмма React в реальном времени с react.context и socket.io
Как сравнить объекты двух разных массивов в javascript