Как избежать утечек памяти при размонтировании?
Продвинутые темы
Утечки при размонтировании избегают очисткой ресурсов: в `useEffect` возвращают cleanup-функцию, которая отменяет таймеры, обработчики, подписки и запросы.
Проблема
При размонтировании компонента незачищенные ресурсы (таймеры, обработчики, подписки, запросы) продолжают жить, удерживая ссылки → утечка и лишняя работа (в React до 18 ещё и предупреждение «обновление размонтированного компонента»; с React 18 его убрали).
Решение — cleanup в useEffect
useEffect возвращает функцию очистки, вызываемую при размонтировании (и перед следующим эффектом):
useEffect(() => {
const id = setInterval(tick, 1000);
const handler = () => {};
window.addEventListener('resize', handler);
const subscription = store.subscribe(update);
const controller = new AbortController();
fetch(url, { signal: controller.signal });
return () => {
clearInterval(id); // таймер
window.removeEventListener('resize', handler); // обработчик
subscription.unsubscribe(); // подписка
controller.abort(); // запрос
};
}, []);Что чистить
- Таймеры —
clearInterval/clearTimeout. - Обработчики событий —
removeEventListener. - Подписки — отписаться (store, WebSocket, RxJS).
- Запросы — отменить (
AbortController). - Web Workers —
terminate. - Анимации —
cancelAnimationFrame.
В классовых компонентах
componentWillUnmount — та же очистка.
Дополнительно
- Флаг
isMountedилиAbortController, чтобы не обновлять состояние после размонтирования.
Коротко для собеседования
Утечки при размонтировании избегают cleanup-функцией в useEffect (return () => {...}), которая при размонтировании чистит: таймеры (clearInterval), обработчики (removeEventListener), подписки (unsubscribe), запросы (AbortController.abort), воркеры (terminate), анимации (cancelAnimationFrame). В классах — componentWillUnmount. Иначе — утечки и лишняя работа после размонтирования.