Cleaning up window event listeners
In this example, we have a component named WindowSize
that updates its state with the window's width and height whenever a window resize event occurs. To achieve this, we use the useEffect
hook with an empty dependency array, ensuring the effect only runs on mount and unmount. The effect's body executes on mount, and the returned function executes on unmount.
Whenever we use
window.addEventListener()
inside auseEffect
hook, we must remove the event listener when the component unmounts to avoid adding global event listeners repeatedly and potentially causing memory leaks.
import React, { useState, useEffect } from 'react';
export default function WindowSize() {
const [size, setSize] = useState({
width: 0,
height: 0,
});
useEffect(() => {
// Define the listener callback function
const onWindowResize = () => {
setSize({
width: window.innerWidth,
height: window.innerHeight,
});
};
// Initialize state with current window size
onWindowResize();
// Add window resize event listener on mount
window.addEventListener('resize', onWindowResize);
return () => {
// Remove window resize event listener on unmount
window.removeEventListener('resize', onWindowResize);
};
}, []);
return (
<p>
Window width: {size.width}
<br />
Window height: {size.height}
</p>
);
}
Cleaning up setInterval and setTimeout
Similarly, when using setInterval
or setTimeout
inside a useEffect
hook, it's important to clear these timers on unmount to prevent them from running indefinitely and causing unexpected behavior.
import React, { useState, useEffect } from 'react';
export default function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
// Start interval on mount
const intervalId = setInterval(() => {
setSeconds((prevSeconds) => prevSeconds + 1);
}, 1000);
return () => {
// Clear the interval on unmount
clearInterval(intervalId);
};
}, []);
return <div>Seconds passed: {seconds}</div>;
}
Proper cleanup helps prevent memory leaks and ensures that our components behave as expected. Whether adding event listeners or setting intervals, always remember to clean up when the component unmounts.