> Что функция, передаваемая в useEffect, может возвращать и зачем (React)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Kaspersky

Стек: React

> Пример ответа

Короткий ответ

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

Подробное объяснение

useEffect принимает callback, который может опционально возвращать функцию. Эта функция называется cleanup и выполняется в двух сценариях:

  • при размонтировании компонента (когда компонент удаляется из DOM)
  • перед каждым повторным запуском эффекта (если изменились зависимости)

Cleanup гарантирует, что предыдущий эффект корректно завершён до начала нового. Это критично для:

  • отмены fetch-запросов через AbortController
  • очистки setTimeout/setInterval
  • удаления event listeners
  • отписки от WebSocket или Observable
  • сброса DOM-мутаций

React вызывает cleanup в порядке, обратном выполнению эффектов, и только для эффектов, которые уже были запущены. Если dependencies пусты ([]), cleanup выполняется только при unmount.

На практике

В production-коде cleanup - обязательный паттерн для любого эффекта, создающего долгоживущие ресурсы. Без него возможны:

  • race conditions при асинхронных запросах (ответ от предыдущего запроса может перезаписать актуальные данные)
  • утечки памяти из-за "висящих" таймеров
  • ошибки при попытке обновить размонтированный компонент

Типичный пример - поиск с debounce: cleanup отменяет предыдущий таймер, если пользователь ввёл новый символ до истечения задержки.

Пример кода

JSX
useEffect(() => {
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.then(res => res.json())
.then(setData)
.catch(err => {
if (err.name !== 'AbortError') console.error(err);
});
return () => controller.abort(); // cleanup
}, [id]);

Как отвечать на собеседовании

Начни с чёткого определения: "функция очистки, вызываемая при unmount или перед re-run". Приведи конкретные примеры из практики: отмена запросов, очистка таймеров, удаление listener'ов. Подчеркни, что React вызывает cleanup в правильном порядке и только для активных эффектов. Упомяни, что если dependencies пусты, cleanup сработает только при unmount. Избегай абстрактных рассуждений - покажи понимание жизненного цикла эффекта.

Что проверяет интервьюер

  • Понимание жизненного цикла эффекта (mount → update → unmount)
  • Знание механизма cleanup и его тайминга
  • Осознание последствий отсутствия cleanup (утечки, race conditions)
  • Умение применять на практике (AbortController, clearInterval, removeEventListener)
  • Понимание разницы между cleanup при unmount и перед re-run

Типичные ошибки

  • Возврат не функции, а другого значения (React выведет warning в dev mode)
  • Забывают про cleanup для setInterval - таймер продолжает работать после unmount
  • Пытаются использовать async функцию напрямую в useEffect (она возвращает Promise, а не cleanup)
  • Путают cleanup с componentWillUnmount - cleanup вызывается и перед re-run, а не только при unmount
  • Не используют AbortController для fetch, полагаясь только на флаг mounted (не защищает от race conditions)

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью