PassFront
  1. PassFront
  2. База знаний
  3. Хуки

Для чего нужна cleanup у useEffect?

Хуки

Cleanup — функция, возвращаемая из эффекта. Нужна, чтобы отменять/убирать то, что эффект начал: без неё подписки, таймеры и запросы «переживают» компонент и накапливаются.

Когда вызывается

  • Перед каждым повторным запуском эффекта (изменились зависимости) — сначала прибраться за старым, затем запустить новый.
  • При размонтировании компонента.

Задачи cleanup

Отписки от событий и каналов:

useEffect(() => {
  const onResize = () => setWidth(window.innerWidth);
  window.addEventListener('resize', onResize);
  return () => window.removeEventListener('resize', onResize);
}, []);

Без отписки: утечка памяти + обработчики-«зомби», дёргающие setState размонтированного компонента.

Очистка таймеров:

useEffect(() => {
  const id = setInterval(poll, 5000);
  return () => clearInterval(id);
}, []);

Закрытие соединений (WebSocket, EventSource), иначе с каждым перемонтированием их становится больше.

Отмена запросов / защита от гонок:

useEffect(() => {
  const ctrl = new AbortController();
  fetch(`/api/user/${id}`, { signal: ctrl.signal })
    .then((r) => r.json())
    .then(setUser)
    .catch(() => {});
  return () => ctrl.abort(); // старый запрос не перезапишет новый ответ
}, [id]);

При быстрой смене id ответы могут прийти в обратном порядке — cleanup отменяет устаревший.

Почему это критично

StrictMode (dev, React 18) специально монтирует компонент дважды: эффект → cleanup → эффект. Если cleanup честный — приложение не заметит; если нет — дубли запросов и подписок проявятся сразу, а не «загадочно в проде».

Коротко для собеседования

Cleanup отменяет начатое эффектом: отписки, clearInterval, закрытие соединений, abort запросов (защита от гонок). Вызывается перед каждым перезапуском эффекта и при размонтировании; его корректность проверяет двойное монтирование StrictMode. Правило: каждый эффект с подпиской/таймером обязан вернуть cleanup.

Другие вопросы раздела