Что делает хук useEffect и как работает функция очистки в React?
Что проверяют
Понимаете ли вы, что эффект это синхронизация с внешним миром, и знаете ли, когда именно вызывается очистка.
Как отвечать
useEffect выполняет побочный эффект после отрисовки: подписка, запрос, таймер, работа с DOM напрямую. Массив зависимостей задаёт, когда эффект повторяется.
Функция очистки это то, что эффект возвращает. React вызывает её перед каждым повторным запуском эффекта и при размонтировании:
useEffect(() => {
const id = setInterval(tick, 1000);
return () => clearInterval(id); // снимаем предыдущий таймер
}, [delay]);Порядок при смене зависимостей такой: очистка предыдущего эффекта, потом новый эффект. Именно поэтому подписка не накапливается: каждый новый запуск отменяет предыдущий.
Что важно про зависимости: пустой массив это «один раз при монтировании», отсутствие массива это «после каждой отрисовки», перечисленные значения это «когда изменилось хотя бы одно». Врать в зависимостях нельзя, устаревшее замыкание захватит старое значение и будет работать с ним.
Отдельно про строгий режим в разработке: React намеренно монтирует, размонтирует и монтирует компонент снова, чтобы очистка сработала и стали видны эффекты, которые её не имеют. Это не баг, а проверка.
Для гонок запросов используют AbortController или флаг отмены в очистке, иначе ответ на устаревший запрос перезапишет свежий.
Где спотыкаются
Не возвращают очистку у подписок и таймеров и получают утечки.
Ставят пустой массив зависимостей, чтобы «не мигало», и работают со старыми значениями.
Считают двойной вызов в разработке ошибкой React.
Не отменяют запрос при смене зависимости, из-за чего медленный ответ перетирает быстрый.