Как реализовать unmount через useEffect?
Хуки
«Поймать» размонтирование в функциональном компоненте можно единственным способом: вернуть cleanup-функцию из useEffect с пустым массивом зависимостей.
Базовый паттерн
useEffect(() => {
// (опционально) код при монтировании
return () => {
// код при размонтировании — аналог componentWillUnmount
console.log('компонент удалён из дерева');
};
}, []); // пустой массив: эффект не перезапускается,
// значит cleanup вызовется только при unmountКлюч — именно []: если указать зависимости, cleanup будет вызываться и перед каждым перезапуском эффекта, а не только при размонтировании.
Практические примеры
// отписка от событий
useEffect(() => {
window.addEventListener('online', handler);
return () => window.removeEventListener('online', handler);
}, []);
// закрытие соединения
useEffect(() => {
const ws = new WebSocket(url);
return () => ws.close();
}, []);
// отмена запроса
useEffect(() => {
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal }).then(...);
return () => controller.abort();
}, []);Нюансы
- Cleanup замыкает значения своего рендера — для доступа к «самым свежим» данным при размонтировании используют ref.
- StrictMode (dev) смонтирует-размонтирует-смонтирует компонент: cleanup выполнится и без «настоящего» размонтирования — код должен быть к этому готов.
- Если нужно и на изменение зависимостей, и на unmount — это одно и то же cleanup: React сам вызовет его в обоих случаях при непустых deps.
Коротко для собеседования
Unmount через useEffect — это useEffect(() => { return () => {...}; }, []): с пустым массивом cleanup выполнится только при размонтировании. Использовать для отписок, закрытия соединений, отмены запросов; помнить про двойное срабатывание в StrictMode.