useEffect

Хук useEffect позволяет выполнять побочные эффекты в функциональных компонентах. Побочные эффекты — это действия, которые влияют на внешнюю среду или не могут быть выполнены во время чистого рендеринга: например, запросы к API, подписки на события, прямые манипуляции с DOM, таймеры и работа с внешними системами.

Синтаксис

useEffect(() => {
  // код побочного эффекта
  return () => {
    // опциональная функция очистки
  };
}, [зависимости]);

Первый аргумент — функция, которая содержит логику эффекта.
Второй аргумент — массив зависимостей. Он управляет, когда эффект должен запускаться повторно.

Варианты использования

Без массива зависимостей

Если второй аргумент отсутствует, эффект выполняется после каждого рендера компонента.

useEffect(() => {
  console.log('Компонент обновился');
});

Это может привести к избыточным вызовам и снижению производительности — используйте осторожно.

Пустой массив зависимостей

Если передать пустой массив [], эффект выполнится один раз — при монтировании компонента. Это аналог componentDidMount в классах.

useEffect(() => {
  fetchData();
}, []);

Зависимости указаны

Если в массиве перечислены переменные, эффект будет перезапускаться при изменении любого из них.

useEffect(() => {
  document.title = `Пользователь: ${name}`;
}, [name]);

React сравнивает значения зависимостей посредством строгого равенства (Object.is). Поэтому для объектов и массивов важно сохранять ссылочную стабильность (например, через useMemo или вынос в константу).

Очистка эффекта

Если функция внутри useffect возвращает другую функцию, React вызовет её:

  • перед следующим запуском эффекта (если зависимости изменились);
  • при размонтировании компонента.

Это используется для отмены подписок, таймеров, слушателей и других ресурсов.

Пример:

useEffect(() => {
  const handleResize = () => console.log('Окно изменено');
  window.addEventListener('resize', handleResize);

  return () => {
    window.removeEventListener('resize', handleResize);
  };
}, []);

Без очистки возможны утечки памяти или ошибки при попытке взаимодействия с уже удалённым компонентом.

Распространённые случаи

  • Загрузка данных при монтировании (fetch + useState)
  • Подписка на события браузера или внешние источники
  • Ручное обновление DOM вне React-потока
  • Логирование или аналитика

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