Function components do not have a componentWillUnmount method. To clean up work tied to a component, return a cleanup function from useEffect. React runs it when the component is removed—and also before it reruns that Effect because a dependency changed.
How to clean up when a function component unmounts
Put cleanup in the function returned by an Effect’s setup function. This is the usual function-component pattern for external work that needs to be undone or stopped, such as a connection or subscription.
import { useEffect } from 'react';
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [roomId]);
return <h1>{roomId}</h1>;
}
Here, the Effect connects to the room named by roomId. Its returned function disconnects that connection. The dependency list includes roomId because the Effect reads it. See React’s useEffect reference and guide to synchronizing with Effects.
Cleanup can run before unmount
Cleanup is not reserved for the moment a component disappears. When a dependency changes, React first runs the previous cleanup using the values captured by that Effect, then runs the Effect again with the new values. When the component is removed, React runs the final cleanup. This is why the example disconnects the old room before connecting to a newly selected one.
#1 Best Overall
Make cleanup mirror setup: disconnect what the Effect connected, unsubscribe what it subscribed to, and stop or undo other external work the setup started.
Why cleanup may seem to run unexpectedly
A dependency changed
If the component is still visible when cleanup runs, check whether an Effect dependency changed. React runs cleanup before setting up the Effect again with the new dependency values; that is not necessarily an unmount.
Strict Mode is enabled in development
React Strict Mode performs an extra setup-and-cleanup cycle in development to reveal Effects whose cleanup does not correctly undo setup. That development check does not mean the component was removed in production. Consult the StrictMode reference.
The Effect runs after every commit
If you omit the dependency array, React reruns the Effect after every commit. If you provide dependencies, one that changes on every render can also cause repeated cleanup and setup. Check the values the Effect reads and whether those values are stable when they should be.
Rank #3
Choose the Effect timing that fits the work
Use useEffect for ordinary external synchronization
useEffect is the normal choice for synchronizing with external systems, such as managing a connection. React runs Effects on the client; they do not run during server rendering.
Use useLayoutEffect only when work must happen before paint
useLayoutEffect runs before the browser repaints, which can be appropriate for visual measurement or updates that must happen before the user sees the screen. It blocks painting, so use it only when that timing is necessary. React describes it in the useLayoutEffect reference.
Rank #4
When not to add an Effect
An Effect is for synchronizing with something outside React. If code only calculates values for rendering and does not synchronize with an external system, an Effect may be unnecessary. React’s guide, You Might Not Need an Effect, explains when to avoid one.
For class-component lifecycle methods and their function-component alternatives, see React’s Component reference.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




