Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Effects, refs и внешние системы
effects_refs

Effects, refs и внешние системы

useEffect как синхронизация, зависимости, cleanup, refs, useEffectEvent, race conditions и отмена работы.

Открыть лабораториюv0.1.0Запускается локально из публичного репозитория

Effects, refs и внешние системы

Effect нужен не после каждого render, а только когда React-состояние синхронизируется с системой вне React.

#Результат урока

Вы удалите лишние Effects, напишете симметричные subscriptions, устраните stale closure и race conditions и примените refs как escape hatch.

До начала достаточно render/commit, state snapshots, closures и async cancellation. В конце должен появиться не конспект, а виджет живого соединения с корректным lifecycle, отменой, latest non-reactive callbacks и фокусом.

#1. Effect синхронизирует внешнюю систему

Effect выполняется после commit и приводит внешний ресурс в соответствие текущим props/state: соединение, browser API, widget, subscription. Если значение можно вычислить во время render или действие вызвано handler, Effect не нужен. Формулируйте ресурс и симметричный cleanup до написания кода.

Рабочая проверка. Для каждого Effect назовите внешнюю систему; удалите Effect без такой системы.

Типичная поломка. Пересчитывать fullName из firstName/lastName через Effect и state.

#2. Setup и cleanup как одна операция

Effect возвращает cleanup, который отменяет именно сделанный setup: remove listener той же функцией, unsubscribe, disconnect, clear timer. Перед новым setup с изменёнными deps React сначала выполняет прежний cleanup; при unmount — последний cleanup. Эта симметрия делает remount безопасным.

Рабочая проверка. Проверьте количество listeners после смены roomId и unmount.

Типичная поломка. Передать removeEventListener новую arrow, не совпадающую с добавленной.

#3. Reactive dependencies без ручного выбора

Все reactive values, прочитанные Effect, входят в deps. Список не является ручной политикой запуска; он следует коду. Чтобы изменить deps, измените code structure: перенесите object внутрь Effect, вынесите константу из компонента, используйте updater или Effect Event. Подавление lint создаёт stale closure.

Рабочая проверка. Исправьте Effect с object dependency без JSON.stringify и suppression.

Типичная поломка. Оставить пустой массив, хотя Effect читает меняющийся roomId.

#4. Race conditions и отмена

Несколько async операций могут завершиться не по порядку. Cleanup помечает результат устаревшим или abort-ит поддерживаемый fetch. Abort не всегда отменяет серверную работу и может прийти после завершения, поэтому commit результата всё равно связывают с текущим запросом. Ошибка отмены обычно не показывается как сбой пользователю.

Рабочая проверка. Искусственно задержите старый запрос дольше нового и проверьте итог.

Типичная поломка. Применять любой последний завершившийся ответ независимо от входа Effect.

#5. Refs для неотображаемых mutable values

Ref сохраняет объект между renders и не вызывает render при записи. Подходит для DOM handle, timer id, latest imperative instance и данных, которые не влияют на JSX. Не читайте и не пишите ref.current во время render, кроме предсказуемой ленивой инициализации; это нарушает чистоту.

Рабочая проверка. Сохраните timer id в ref, очистите его при повторном запуске и unmount.

Типичная поломка. Хранить status, который отображается пользователю, только в ref.

#6. useLayoutEffect и layout

useLayoutEffect запускает setup после DOM mutations, но до paint, и может синхронно вызвать render. Он нужен для измерения layout и корректировки, которую пользователь не должен увидеть промежуточной. Блокирует paint, поэтому network, logging и обычные subscriptions остаются в useEffect. На сервере layout отсутствует.

Рабочая проверка. Измерьте tooltip и разместите его до paint, затем сравните с обычным Effect.

Типичная поломка. Заменить все Effects на layout Effects «для надёжности».

#7. useEffectEvent для non-reactive чтения

Effect Event позволяет Effect вызвать логику, которая всегда читает latest props/state, но не должна сама делать Effect реактивным. Например, соединение зависит от roomId, а уведомление использует текущую theme. Effect Event вызывают только из Effects и не передают как общий callback. Это не способ скрыть настоящую dependency.

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

const onConnected = useEffectEvent(() => { showNotification('Подключено', theme); }); useEffect(() => { const connection = connect(roomId); connection.on('connected', onConnected); return () => connection.close(); }, [roomId]);

Смена theme меняет вид уведомления, но не является причиной переподключения к комнате.

Рабочая проверка. Смените theme без reconnect и проверьте latest theme при следующем connected.

Типичная поломка. Убрать roomId из deps, спрятав его чтение в Effect Event.

#8. Effect review и удаление каскадов

Цепочка Effect A → setState → Effect B → setState создаёт лишние commits и хрупкие промежуточные состояния. Событие пользователя может вычислить все переходы одним handler/reducer. Derived данные вычисляются при render. Effect review классифицирует каждый Effect: external subscription, imperative widget, telemetry view event или кандидат на удаление.

Рабочая проверка. Сверните каскад выбора карточки и сброса round в одно event transition.

Типичная поломка. Координировать бизнес-workflow наблюдением за state после commit.

#Лаборатория

Исправьте чат: соединение пересоздаётся на смену theme, старый fetch перезаписывает новый, listener течёт, а ref читается в render. Примените Effect, cleanup, AbortController и useEffectEvent по контракту.

Критерий завершения: StrictMode setup-cleanup-setup оставляет один ресурс, устаревший ответ не коммитится, зависимости проходят lint без suppression. Сначала зафиксируйте наблюдаемое поведение тестом или измерением, затем меняйте реализацию.

#Источники для сверки

  • React: Synchronizing with Effects
  • React: You Might Not Need an Effect
  • React useEffectEvent
  • React useRef

Устранение неисправностей

Проверьте свои знания

Вопросы ещё не добавлены

Вопросы для этой подтемы ещё не добавлены.

Далее: Пользовательские хуки