бесконечный цикл реакции useEffect hook, вызванный токеном отмены axios [response-hooks / исчерпывающе-deps] - PullRequest
0 голосов
/ 06 ноября 2019

В моем компоненте реакции я использую useEffect для извлечения данных при монтировании компонента и каждый раз, когда меняются фильтры. Все работает как надо, но react-hooks/exhaustive-deps выдает предупреждение, что функция fetcher должна быть в массиве зависимостей. Добавляя сборщик в список зависимостей, приложение попадает в бесконечный цикл. Сборщик получает новый токен отмены Axios при каждом запуске, который вызывает бесконечный цикл вызовов сборщика. Как мне справиться с этой ситуацией, не отключая правило?

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

const [isLoading, setIsLoading] = React.useState<boolean>(false);
const [users, setUsers] = React.useState<IUser[]>([]);
const [filters, setFilters] = React.useState<ITableFilters>({...initFilters});

const fetcher = async (s: CancelTokenSource): Promise<void> => {
    setIsLoading(true);
    const params = { ...filters };
    try {
      const { data} = await fetchAllUsers({
        params,
        cancelToken: s.token
      });
      setUsers(data.users);
      setIsLoading(false);
    } catch (error) {
      handleResponseError(error);// wchich checks axios.isCancel
      setIsLoading(false);
    }
}

  React.useEffect(() => {
    const source = axios.CancelToken.source();
    // tslint:disable-next-line: no-floating-promises
    fetcher(source);
    return function cleanup() {
      source.cancel();
    };
  }, [filters]);

1 Ответ

1 голос
/ 06 ноября 2019

Вы можете использовать useCallback, поэтому ссылка на fetcher должна оставаться прежней, не вызывая больше повторных рендеров.

const fetcher = useCallback(async (s: CancelTokenSource) => {
  setIsLoading(true);
  const params = { ...filters };
  try {
    const { data} = await fetchAllUsers({
      params,
      cancelToken: s.token
    });
    setUsers(data.users);
    setIsLoading(false);
  } catch (error) {
    handleResponseError(error);// wchich checks axios.isCancel
    setIsLoading(false);
  }
}, [setIsLoading, setUsers, filters])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...