useUnmount
A Hook for executing a callback when the component unmounts, equivalent to componentWillUnmount in class components.
Basic Usage
Live Editor
function Demo() { const [visible, setVisible] = useState(true); const ChildComponent = () => { useUnmount(() => { console.log('Component unmounted'); }); return ( <div style={{ padding: '20px', backgroundColor: 'var(--ifm-color-success-lightest)', borderRadius: '8px', border: '1px solid var(--ifm-color-success)', }} > This component will log to console when unmounted </div> ); }; return ( <div> <Button onClick={() => setVisible(!visible)}> {visible ? 'Unmount Component' : 'Mount Component'} </Button> <div style={{ marginTop: '12px' }}>{visible && <ChildComponent />}</div> </div> ); }
Result
Loading...
Cleanup Timer
Clear timer on component unmount:
Live Editor
function Demo() { const [show, setShow] = useState(true); const Timer = () => { const [count, setCount] = useState(0); useDidMount(() => { const timer = setInterval(() => { setCount((c) => c + 1); }, 1000); return () => clearInterval(timer); }); useUnmount(() => { console.log('Timer cleaned up, final count:', count); }); return ( <div style={{ padding: '20px', backgroundColor: 'var(--ifm-color-emphasis-100)', borderRadius: '8px', textAlign: 'center', }} > <div style={{ fontSize: '32px', fontWeight: 'bold' }}>{count}</div> <div style={{ fontSize: '14px', color: 'var(--ifm-color-emphasis-700)' }}>Seconds</div> </div> ); }; return ( <div> <Button onClick={() => setShow(!show)}>{show ? 'Stop Timer' : 'Start Timer'}</Button> <div style={{ marginTop: '12px' }}>{show && <Timer />}</div> </div> ); }
Result
Loading...
Cancel API Request
Cancel pending requests on component unmount:
Live Editor
function Demo() { const [show, setShow] = useState(true); const DataFetcher = () => { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const abortController = useRef(null); useDidMount(() => { abortController.current = new AbortController(); // Simulate API request setTimeout(() => { if (abortController.current && !abortController.current.signal.aborted) { setData({ message: 'Data loaded successfully' }); setLoading(false); } }, 2000); }); useUnmount(() => { // Cancel request if (abortController.current) { abortController.current.abort(); console.log('API request cancelled'); } }); if (loading) { return <Loading />; } return ( <div style={{ padding: '20px', backgroundColor: 'var(--ifm-color-success-lightest)', borderRadius: '8px', }} > {data?.message} </div> ); }; return ( <div> <Button onClick={() => setShow(!show)}>{show ? 'Unmount' : 'Mount'}</Button> <div style={{ marginTop: '12px' }}>{show && <DataFetcher />}</div> </div> ); }
Result
Loading...
Save State
Save component state on unmount:
Live Editor
function Demo() { const [show, setShow] = useState(true); const Editor = () => { const [content, setContent] = useState(''); useUnmount(() => { if (content) { localStorage.setItem('editor-draft', content); console.log('Draft saved:', content); } }); return ( <div> <Textarea placeholder="Enter content (auto-saved on unmount)" value={content} onChange={(e) => setContent(e.target.value)} rows={4} /> <div style={{ marginTop: '8px', fontSize: '14px', color: 'var(--ifm-color-emphasis-700)' }}> Click "Unmount" button to save to localStorage </div> </div> ); }; return ( <div> <Button onClick={() => setShow(!show)}>{show ? 'Unmount (Save)' : 'Mount'}</Button> <div style={{ marginTop: '12px' }}>{show && <Editor />}</div> </div> ); }
Result
Loading...
API
Parameters
function useUnmount(fn: () => void): void;
| Parameter | Description | Type | Default |
|---|---|---|---|
| fn | Callback function to execute on component unmount | () => void | - |
Return Value
No return value.
Features
- Stable Reference: Correctly executes the latest function even if the callback changes
- Auto Cleanup: Automatically executes on component unmount
- Simple to Use: No need to manually manage useEffect cleanup function
Notes
- Only executes once on component unmount
- Callback function reference automatically updates to latest version
- Don't execute operations that cause side effects (like setState) in the callback
Usage Scenarios
- Clear Timers: Clean up setTimeout/setInterval
- Cancel Requests: Cancel incomplete API requests
- Remove Listeners: Remove event listeners
- Save State: Save component state to localStorage
- Release Resources: Release subscriptions, connections, and other resources
- Logging: Record component lifecycle