Вопрос с собеседования · Frontend

Как работает useEffect и что такое массив зависимостей?

JuniorReact
Ещё спрашивают так:
  • Зачем useEffect возвращает функцию?
  • Почему эффект срабатывает дважды в режиме разработки?
Коротко

useEffect запускает побочный эффект после отрисовки: подписки, таймеры, запросы, синхронизацию с внешней системой. Зависимости определяют, когда эффект перезапускается: [] — один раз после монтирования, [a, b] — при изменении a или b, без массива — после каждого рендера. Возвращённая функция — очистка перед следующим запуском и при размонтировании.

  • В зависимостях — всё, что эффект читает из компонента; линтер exhaustive-deps проверяет
  • StrictMode в разработке монтирует дважды — проверка, что очистка корректна
  • Вычисление данных из props — не эффект, а обычный код рендера

А ещё Запросы данных лучше через библиотеки (TanStack Query) — кэш, гонки, отмена

Подробно

Модель: эффект синхронизирует компонент с чем-то вне React. При каждом изменении зависимостей React сначала вызывает очистку предыдущего эффекта, затем новый эффект.

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

  • пропущенная зависимость — эффект видит устаревшие значения (замыкание из старого рендера);
  • объект или функция, создаваемые в рендере, в зависимостях — эффект срабатывает каждый раз; выносить наружу, useMemo/useCallback или зависеть от примитивов;
  • setState в эффекте без условия — бесконечный цикл;
  • отсутствие очистки — утечки подписок, гонки запросов (ответ на старый id приходит позже нового).

Не нужен эффект, когда значение можно вычислить из props и state при рендере, или когда реакция на действие пользователя — это код в обработчике события.

Пример

useEffect(() => {
  const controller = new AbortController();
  fetch(`/api/users/${id}`, { signal: controller.signal })
    .then(r => r.json())
    .then(setUser)
    .catch(e => { if (e.name !== "AbortError") setError(e); });
  return () => controller.abort();     // отменить при смене id и размонтировании
}, [id]);

Что хотят услышать

  • Когда выполняется эффект и роль зависимостей.
  • Очистка.
  • Типичные ошибки и когда эффект не нужен.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗useEffect выполняется до отрисовки, синхронно с рендером
  • ✗Без массива зависимостей эффект выполняется только один раз, сразу после монтирования
  • ✓После отрисовки; [] — один раз, [a, b] — при их изменении; возвращённая функция — очистка
  • ✗Очистка эффекта не нужна для подписок

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования