PassFront
  1. PassFront
  2. База знаний
  3. Жизненный цикл

Как в функциональном компоненте можно реализовать 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.

Другие вопросы раздела