The unmounting phase in React occurs when a component is removed from the DOM. This happens when a component is no longer needed — for example, when the user navigates away from a page or when a conditionally rendered component is hidden.
React provides lifecycle methods and hooks to perform cleanup tasks during unmounting, so that no memory leaks or unwanted behaviors occur after the component is gone.
Unmounting = Component removed + cleanup
componentWillUnmount(): Class component lifecycle method for cleanup.useEffect() cleanup function: Functional component way to run cleanup logic.componentWillUnmount()In class-based components, the componentWillUnmount() lifecycle method runs right before the component is removed from the DOM. It is the perfect place to:
// Class-based Timer that cleans up the interval in componentWillUnmount
import React from "react";
class Timer extends React.Component {
componentDidMount() {
this.interval = setInterval(() => {
console.log("Timer running...");
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
console.log("Timer stopped and cleaned up!");
}
render() {
return <h3>Timer Active</h3>;
}
}
export default Timer;
componentDidMount() starts an interval that logs "Timer running..." every second.componentWillUnmount() clears that interval and logs a final cleanup message.useEffect()In functional components, cleanup during unmounting is handled using the return function inside the useEffect() hook.
Whatever you return from the effect callback runs when the component unmounts (and also before the effect re-runs, if dependencies change).
// Functional Timer that uses useEffect cleanup on unmount
import { useEffect } from "react";
function Timer() {
useEffect(() => {
const interval = setInterval(() => {
console.log("Timer running...");
}, 1000);
return () => {
clearInterval(interval);
console.log("Timer stopped and cleaned up!");
};
}, []);
return <h3>Timer Active</h3>;
}
export default Timer;
Timer mounts, the effect runs and starts the interval.Timer unmounts, the cleanup function returned from useEffect() runs."Timer stopped and cleaned up!" once.A very common pattern is to mount a component when a toggle is ON and unmount it when the toggle is OFF. The code below shows how a parent component can mount/unmount the Timer component.
// Parent component that mounts/unmounts the Timer using a button
import { useState } from "react";
import Timer from "./Timer";
function TimerDemo() {
const [showTimer, setShowTimer] = useState(true);
return (
<div>
<button onClick={() => setShowTimer(!showTimer)}>
{showTimer ? "Hide Timer" : "Show Timer"}
</button>
{showTimer && <Timer />}
</div>
);
}
export default TimerDemo;
showTimer is true, so the <Timer /> component is mounted."Timer running..." every second.showTimer becomes false and Timer unmounts.setInterval() or setTimeout() when leaving a page.window.useEffect() when using side effects like timers or listeners.AbortController to safely cancel network requests on unmount.Timer component that uses setInterval() to log "Timer Active" every second.useEffect() with a cleanup return function to stop the timer when the component unmounts.Goal: Understand how React unmounts components and learn how to perform cleanup tasks using componentWillUnmount() in class components and the cleanup function in useEffect() for functional components.