Очистка эффекта
Разбираем функцию очистки — как убрать за собой таймеры и подписки, чтобы не плодить утечки.
Функция очистки — функция, которую возвращает эффект; React вызывает её перед повторным запуском эффекта и при удалении компонента.
Проблема: эффект, который надо отменять
Некоторые эффекты «оставляют след»: запущенный таймер, подписка на событие, открытое соединение. Если компонент исчезнет, а таймер останется тикать — это утечка ресурсов. Покажем таймер:
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => clearInterval(id); // ← очистка
}, []);
return <p>Прошло секунд: {seconds}</p>;
}
Эффект запускает setInterval и возвращает функцию, которая его останавливает. Когда компонент исчезнет с экрана, React вызовет эту функцию и таймер не повиснет в памяти.
Когда вызывается очистка
Очистка срабатывает в двух случаях:
- Перед повторным запуском эффекта (если изменилась зависимость) — чтобы убрать предыдущую версию перед созданием новой.
- При размонтировании компонента (он исчезает с экрана).
Порядок при изменении зависимости такой: очистка старого эффекта → запуск нового. Это гарантирует, что одновременно не работают две подписки.
Пример с подпиской на событие
Классика — подписка на событие окна. Без очистки при каждой перерисовке навешивался бы новый обработчик, и их накопилось бы множество:
useEffect(() => {
function handleResize() {
console.log("ширина:", window.innerWidth);
}
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize); // снимаем
};
}, []);
Что бывает без очистки
| Эффект | Без очистки |
setInterval | таймер тикает после удаления компонента — утечка |
addEventListener | накапливаются дубли обработчиков |
| подписка на сокет | лишние соединения, повторные данные |
Правило
Простое правило: если эффект что-то «открывает» — он должен это «закрыть» в функции очистки. Подписался — отпишись, запустил таймер — останови, открыл соединение — закрой.
Итог
- Эффект может вернуть функцию очистки; React вызывает её перед повтором эффекта и при удалении компонента.
- Очистка убирает таймеры (
clearInterval), подписки (removeEventListener), соединения — иначе утечки и дубли. - Правило: открыл ресурс в эффекте — закрой его в очистке.