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

Какие вариации использования useEffect важны на практике и как их применять?

Хуки

useEffect — один хук, но паттернов его использования несколько, и на практике нужно знать, какой режим для какой задачи.

Эффект «на монтирование» — []

useEffect(() => {
  analytics.pageView('/checkout');
}, []);

Разовая инициализация: аналитика, первичная загрузка, установка глобальных слушателей. В StrictMode (dev, React 18+) выполнится дважды — код должен это переживать.

Эффект-синхронизация — [deps]

useEffect(() => {
  let cancelled = false;
  fetchUser(userId).then((u) => { if (!cancelled) setUser(u); });
  return () => { cancelled = true; };
}, [userId]);

Основной рабочий режим: перезагрузка данных при смене параметров, переподключение при смене канала. Cleanup защищает от гонок (race conditions) — ответ устаревшего запроса игнорируется.

Подписки с обязательным cleanup

useEffect(() => {
  const handler = (e) => setWidth(e.target.innerWidth);
  window.addEventListener('resize', handler);
  return () => window.removeEventListener('resize', handler);
}, []);

Каждой подписке — отписка, каждому таймеру — clearInterval, иначе утечки памяти и «мёртвые» обработчики.

Эффект после каждого рендера — без массива

Редкий случай: интеграции, которым нужно реагировать на любой рендер (например, синхронизация с императивной библиотекой). Чаще это признак ошибки.

Антипаттерны

  • Вычисление данных из props/state через эффект + setState — лишний цикл рендера; считайте прямо в рендере или в useMemo.
  • Обработка пользовательских действий в эффекте — место этому в обработчике события.
  • «Цепочки» эффектов, триггерящих друг друга через state, — трудно отлаживать, лучше объединить логику.

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

Основные вариации: [] — разовая инициализация; [deps] — синхронизация с данными (обязательно с cleanup от гонок); подписки с отпиской в cleanup; без массива — почти никогда. Эффекты — для внешних систем, а не для вычислений из state.

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