Effect Cleanup Functions
In React, an effect can return a cleanup function to undo or disconnect whatever the effect set up. React runs cleanup before re-running the effect when its dependencies change and when the component is removed from the DOM.
An effect created with `useEffect` may return a function. That returned function is the cleanup function, and it should release resources or undo side effects created by the effect, such as event listeners, timers, subscriptions, or connections.
When an effect runs again because its dependencies changed, React first runs the cleanup from the previous effect, then runs the new effect setup. This ordering prevents the old effect from remaining active while the new one is established.
When a component unmounts, React runs the most recent cleanup for its effects. Cleanup should therefore be written to be safe to call whenever the corresponding setup needs to be undone.
In development, React Strict Mode may perform an additional setup-and-cleanup cycle to help expose effects that do not correctly handle setup and teardown. Cleanup is not a general-purpose place for arbitrary state updates; its main purpose is to stop or reverse the external work established by the effect.
Key points
- Return a function from `useEffect` to define cleanup.
- Cleanup runs before the effect runs again after a dependency change.
- Cleanup runs when the component unmounts.
- Clean up external resources such as timers, listeners, subscriptions, and connections.
- In development Strict Mode, an extra setup/cleanup cycle can reveal missing cleanup logic.
Interview questions
When does React run an effect's cleanup function?
React runs cleanup before the effect's setup runs again when its dependencies have changed. It also runs the cleanup when the component unmounts. This ordering lets React remove the previous effect's external resources before establishing the next version. Development Strict Mode can also cause an additional setup-and-cleanup cycle.
What is an effect cleanup function in React?
It is the function returned from a `useEffect` callback. It is used to undo work performed by the effect, such as removing an event listener or clearing a timer. React calls it when the component unmounts and before the effect runs again because its dependencies changed. The goal is to prevent stale or duplicated external work.
Why would an effect need cleanup?
Effects often interact with systems outside React, and those systems can continue operating after a render has finished. For example, an interval keeps firing and an event listener keeps receiving events until explicitly removed. Cleanup disconnects those resources when the effect is no longer valid. Without it, applications can accumulate duplicate listeners, timers, subscriptions, or connections.
What happens to cleanup when an effect has dependencies?
React compares the dependency values between effect executions. When a dependency changes, React runs the cleanup associated with the previous effect execution before running the new setup. The new setup can therefore establish resources using the latest dependency values. If dependencies do not change, React does not normally re-run that effect because of the dependency array.
How would you explain Strict Mode's extra effect cleanup cycle?
In development, React Strict Mode can intentionally perform an extra setup and cleanup sequence for effects. The purpose is to expose effects whose setup cannot be safely repeated or whose cleanup is incomplete. A well-structured effect should tolerate setup, cleanup, and setup again without leaking resources or producing incorrect external state. This behavior should not be treated as evidence that production necessarily performs the same extra cycle.