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

Как работает return в useEffect?

Хуки

Функция, которую эффект возвращает через return, — это cleanup-функция: React вызывает её, чтобы «прибрать» за предыдущим запуском эффекта.

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

  • Перед каждым повторным запуском эффекта (если изменились зависимости): сначала очистка старого, затем новый эффект.
  • При размонтировании компонента.
useEffect(() => {
  const socket = connectToRoom(roomId);

  return () => socket.disconnect(); // cleanup
}, [roomId]);

Последовательность при смене roomId: рендер → отключение от старой комнаты (cleanup) → подключение к новой (эффект). При размонтировании — только отключение.

Зачем нужен

  • Отписки: removeEventListener, unsubscribe, disconnect.
  • Таймеры: clearTimeout / clearInterval.
  • Отмена запросов / защита от гонок:
useEffect(() => {
  let cancelled = false;
  loadUser(id).then((u) => { if (!cancelled) setUser(u); });
  return () => { cancelled = true; };
}, [id]);

Без cleanup ответ старого запроса может прийти позже нового и перезаписать актуальные данные; плюс setState на размонтированном компоненте — утечка логики.

Нюансы

  • Cleanup «замыкает» значения того рендера, в котором эффект был создан, — отписывается именно от того, на что подписывался.
  • В StrictMode (dev) React монтирует компонент, вызывает эффект, тут же cleanup и эффект снова — так проверяется, что очистка написана корректно.
  • return в эффекте должен возвращать функцию (или ничего), поэтому нельзя писать useEffect(async () => ...): async-функция возвращает Promise.

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

return в useEffect возвращает cleanup-функцию; React вызывает её перед каждым перезапуском эффекта и при размонтировании. Используется для отписок, очистки таймеров и защиты от гонок запросов. Из-за этого эффект нельзя делать async — он должен вернуть функцию, а не Promise.

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