Hooks and effects
Clean up an Effect
Undo subscriptions, timers, connections, and stale asynchronous work before resynchronizing or removing the component.
An Effect that starts synchronization often needs to stop it.
Return a cleanup function:
useEffect(() => {
window.addEventListener('online', handleOnline)
return () => {
window.removeEventListener('online', handleOnline)
}
}, [])
React calls cleanup before this Effect synchronizes again with changed dependencies. It also calls cleanup when the component leaves the tree.
Think in pairs:
- subscribe → unsubscribe
- connect → disconnect
- start timer → clear timer
- add listener → remove listener
- start request → ignore or abort stale result
Without cleanup, remounting the component can add another listener. One browser event then runs the handler several times.
The cleanup must refer to the same subscription or handler that setup created. An anonymous function passed separately to removeEventListener() is a different function and does not remove the listener.
Cleanup should undo the synchronization from that Effect, not reset unrelated application state.
Mount and unmount the component three times, then dispatch one event. The handler should run once. Strict Mode can help reveal this leak during development.
Lesson completed