Как в функциональном компоненте можно реализовать Unmount?
Жизненный цикл
«Unmount» в функциональном компоненте реализуется через cleanup-функцию useEffect с пустым массивом зависимостей — это полный аналог componentWillUnmount.
Рецепт
useEffect(() => {
// (опционально) логика при монтировании
return () => {
// ← выполнится ровно при размонтировании
console.log('unmount');
};
}, []); // пустые deps: эффект не перезапускается,
// значит cleanup вызовется только при удалении из дереваПрактические примеры
// закрыть соединение
useEffect(() => {
const ws = new WebSocket(url);
return () => ws.close();
}, []);
// снять глобальный слушатель
useEffect(() => {
document.addEventListener('keydown', onKey);
return () => document.removeEventListener('keydown', onKey);
}, []);
// остановить таймер
useEffect(() => {
const id = setInterval(tick, 1000);
return () => clearInterval(id);
}, []);Детали
- Если у эффекта есть deps, cleanup выполняется и перед каждым перезапуском — «только при размонтировании» гарантирует именно пустой массив.
- StrictMode (dev, React 18) монтирует компонент дважды: mount → unmount → mount, cleanup сработает и без «настоящего» размонтирования — код должен быть идемпотентным.
- Cleanup замыкает значения своего рендера; нужно «самое свежее» значение в момент unmount — держите его в useRef и читайте ref.current в cleanup.
- Вынести в переиспользуемый вид: кастомный хук
useUnmount(fn)(внутри — тот же useEffect + ref на fn).
Коротко для собеседования
Unmount-логика: useEffect(() => () => {...}, []) — cleanup с пустыми deps выполняется только при размонтировании (отписки, close, clearInterval). Помнить: с deps cleanup срабатывает и между перезапусками, StrictMode дублирует монтирование, а свежие значения в cleanup достаются через ref.