> Как использовать useEffect для вызова кода при монтировании компонента (React)

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

Компании: Альфа-банк, IT-One

Стек: React

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

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

Чтобы вызвать код при монтировании компонента с помощью useEffect, передайте пустой массив зависимостей вторым аргументом: useEffect(() => { ... }, []). Это гарантирует выполнение эффекта только один раз после первого рендера. Для очистки (например, отписки от событий) верните функцию из эффекта.

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

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

Важно понимать, что React выполняет эффекты после того, как браузер отрисовал изменения. Если эффект содержит асинхронные операции (например, fetch), они запускаются после рендера, не блокируя UI.

Функция очистки, возвращаемая из эффекта, вызывается при размонтировании компонента. Это позволяет корректно завершить подписки, таймеры или отменить запросы. Без очистки могут возникнуть утечки памяти или ошибки при обновлении размонтированного компонента.

На практике

Для вызова кода при монтировании используйте пустой массив зависимостей. Это типично для:

  • загрузки начальных данных с сервера
  • установки подписок на внешние события (WebSocket, resize)
  • инициализации сторонних библиотек
  • запуска таймеров или интервалов

Если эффект зависит от пропсов или состояния, добавьте их в массив зависимостей. Пустой массив означает, что эффект не зависит ни от чего и выполняется один раз. Избегайте включения в массив функций или объектов, создаваемых при каждом рендере - это приведёт к бесконечным перезапускам.

Пример кода

JSX
import { useEffect, useState } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
// Выполняется только при монтировании
const controller = new AbortController();
fetch(`/api/users/${userId}`, { signal: controller.signal })
.then(res => res.json())
.then(data => setUser(data))
.catch(err => {
if (err.name !== 'AbortError') {
console.error(err);
}
});
// Функция очистки при размонтировании
return () => controller.abort();
}, [userId]); // Зависимость от userId
return <div>{user ? user.name : 'Loading...'}</div>;
}

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

Начните с чёткого определения: useEffect с пустым массивом зависимостей. Объясните, что это гарантирует однократное выполнение после монтирования. Упомяните функцию очистки и её важность для предотвращения утечек. Приведите примеры: загрузка данных, подписки, таймеры.

Подчеркните разницу между [] и [dependency]: первый - только при монтировании, второй - при монтировании и при изменении зависимости. Упомяните, что useEffect выполняется после рендера, а не до него.

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

  • Понимание жизненного цикла эффектов и их привязки к рендеру
  • Умение различать монтирование, обновление и размонтирование
  • Знание функции очистки и её практического применения
  • Осознание потенциальных проблем: утечки памяти, stale closures, бесконечные циклы
  • Способность выбрать правильные зависимости для эффекта

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

  • Забывают передать массив зависимостей - эффект выполняется после каждого рендера
  • Используют пустой массив, когда эффект должен реагировать на изменения пропсов или состояния
  • Не возвращают функцию очистки для подписок или таймеров
  • Включают в массив функции или объекты, создаваемые при каждом рендере, вызывая бесконечный цикл
  • Пытаются сделать эффект асинхронным напрямую (async effect) - это не поддерживается, нужно использовать внутреннюю асинхронную функцию

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

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