Как остановить утечку памяти при использовании - PullRequest
1 голос
/ 21 сентября 2019

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

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

Эффект Хук:

useEffect(() => {
setPageLoading(true);
props
  .dispatch(fetchCourses())
  .then(() => {
    setPageLoading(false);
  })
  .catch((error: string) => {
    toast.error(error);
    setPageLoading(false);
  });
}, []);

Страница таблицы реакции:

<ReactTable
  className="-striped -highlight"
  columns={columns}
  data={coursesData}
  defaultPage={currentPage}
  defaultPageSize={courses.perPage}
  loading={isLoading}
  manual={true}
  onFetchData={setFilter}
/>

Установить функцию фильтра:

const setFilter = (pagination: any) => {
  props.dispatch(updateCoursePageSize(pagination.pageSize));
  props.dispatch(updateCourseCurrentPage(pagination.page + 1));
  setCurrentPage(pagination.page);
  setPerPage(pagination.pageSize);
  setLoading(true);
  props.dispatch(fetchCourses()).then(() => {
    setLoading(false);
  });
};

Кто-нибудь знает, как почистить крючок в реакции

1 Ответ

2 голосов
/ 21 сентября 2019

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

useEffect(() => {
  let unmounted = false;

  setPageLoading(true);

  props
    .dispatch(fetchCourses())
    .then(() => {
      if (!unmounted) {
        setPageLoading(false);
      }
    })
    .catch((error: string) => {
      if (!unmounted) {
        toast.error(error);
        setPageLoading(false);
      }
    });

  return () => { unmounted = true };
}, []);

РЕДАКТИРОВАТЬ: если вам нужен вызов, который запускается за пределами useEffect, то ему все равно нужно будет проверить неустановленную переменную, чтобы сообщитьдолжен ли он пропустить вызов setState.Эта несмонтированная переменная будет установлена ​​с помощью useEffect, но теперь вам нужно преодолеть некоторые препятствия, чтобы сделать переменную доступной вне эффекта.

const Example = (props) => {
  const unmounted = useRef(false);
  useEffect(() => {
    return () => { unmounted.current = true }
  }, []);

  const setFilter = () => {
    // ...
    props.dispatch(fetchCourses()).then(() => {
      if (!unmounted.current) {
        setLoading(false);
      }
    })
  }

  // ...
  return (
    <ReactTable onFetchData={setFilter} /* other props omitted */ />
  );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...