The cleanup function prevents memory leaks.
Situation where your application tries to update a state memory location that no longer exists — and removes unnecessary and unwanted behaviors.
Frees application from unwanted behaviors by cleaning up effects; tidying up our code before our component unmounts.
useEffect(() => { effect(); return () => { cleanup(); }; }, [dependencies]);
AbortController
AbortController
is a built-in JavaScript API that allows you to abort one or more DOM requests as and when desired.
useEffect(() => { const controller = new AbortController(); (async () => { try { const response = await fetch(APIEndpoint, { // attach the controller to the request signal: controller.signal, }); } catch (e) { ... } })(); //abort the request when the component unmounts return () => controller?.abort(); }, []);
Cleanup function runs before unmounting
and also runs right before the execution
of the next scheduled effect.
import React, { useState, useEffect } from 'react'; function MouseTracker() { const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 }); useEffect(() => { // Define the event handler const handleMouseMove = (event) => { setMousePosition({ x: event.clientX, y: event.clientY }); }; // Add the event listener when the component mounts window.addEventListener('mousemove', handleMouseMove); // Cleans up the event listener when the component unmounts OR each time when the effect runs (including re-runs) return () => { window.removeEventListener('mousemove', handleMouseMove); }; }, []); // Empty dependency array ensures this runs only once => when the component mounts return ( <div> <h1>Mouse Position</h1> <p>X: {mousePosition.x}</p> <p>Y: {mousePosition.y}</p> </div> ); } export default MouseTracker;
The cleanup function inside the return removes the event listener when the component unmounts OR when the effect runs again.
This prevents memory leaks or unnecessary event listeners after the component is no longer needed.
Memory leak is when a memory is not released after no longer being needed by the application.
This causes the application to use more and more memory over time which leads to performance degradation and even crash.
import React, { useState, useEffect } from 'react'; function Counter() { const [count, setCount] = useState(0); useEffect(() => { const intervalId = setInterval(() => { setCount((prevCount) => prevCount + 1); }, 1000); // No cleanup function here, so the interval is never cleared }, []); return <div>{count}</div>; } export default Counter;
In above example, the interval counter will continue to run in the background and more resources will be consumed over time.