useDidUpdate
A Hook that executes a callback when the component updates, skipping the initial mount, equivalent to the componentDidUpdate lifecycle method in class components.
Basic Usage
Live Editor
function Demo() { const [count, setCount] = useState(0); const [updateCount, setUpdateCount] = useState(0); useDidUpdate(() => { setUpdateCount((c) => c + 1); }, [count]); return ( <div> <div style={{ padding: '20px', backgroundColor: 'var(--ifm-color-emphasis-100)', borderRadius: '8px', marginBottom: '12px', }} > <div>Count: {count}</div> <div style={{ color: 'var(--ifm-color-primary)' }}> Update count: {updateCount} </div> </div> <Button onClick={() => setCount(count + 1)}>Increment</Button> </div> ); }
Result
Loading...
Monitor Specific Values
Execute only when specific dependencies change:
Live Editor
function Demo() { const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [log, setLog] = useState([]); useDidUpdate(() => { setLog((logs) => [...logs, `Name updated to: ${name}`]); }, [name]); return ( <div> <div style={{ marginBottom: '12px' }}> <Input placeholder="Enter name" value={name} onChange={(e) => setName(e.target.value)} /> </div> <div style={{ marginBottom: '12px' }}> <Input placeholder="Enter email (won't trigger log)" value={email} onChange={(e) => setEmail(e.target.value)} /> </div> {log.length > 0 && ( <div style={{ padding: '12px', backgroundColor: 'var(--ifm-color-emphasis-100)', borderRadius: '6px', fontSize: '14px', }} > <strong>Update log:</strong> {log.map((item, index) => ( <div key={index}>• {item}</div> ))} </div> )} </div> ); }
Result
Loading...
Sync to localStorage
Sync to local storage when value changes:
Live Editor
function Demo() { const [text, setText] = useState(''); const [saved, setSaved] = useState(false); useDidUpdate(() => { localStorage.setItem('draft-text', text); setSaved(true); const timer = setTimeout(() => setSaved(false), 2000); return () => clearTimeout(timer); }, [text]); return ( <div> <Textarea placeholder="Enter text (auto-save)" value={text} onChange={(e) => setText(e.target.value)} rows={4} /> {saved && ( <div style={{ marginTop: '12px', padding: '8px 12px', backgroundColor: 'var(--ifm-color-success-lightest)', borderRadius: '4px', fontSize: '14px', }} > ✓ Saved </div> )} </div> ); }
Result
Loading...
Form Validation
Execute validation when fields change:
Live Editor
function Demo() { const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [error, setError] = useState(''); useDidUpdate(() => { if (password && confirmPassword) { if (password !== confirmPassword) { setError('Passwords do not match'); } else { setError(''); } } }, [password, confirmPassword]); return ( <div> <div style={{ marginBottom: '12px' }}> <Input type="password" placeholder="Enter password" value={password} onChange={(e) => setPassword(e.target.value)} /> </div> <div style={{ marginBottom: '12px' }}> <Input type="password" placeholder="Confirm password" value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} /> </div> {error && ( <div style={{ padding: '8px 12px', backgroundColor: 'var(--ifm-color-danger-lightest)', color: 'var(--ifm-color-danger-dark)', borderRadius: '4px', fontSize: '14px', }} > {error} </div> )} </div> ); }
Result
Loading...
API
Parameters
function useDidUpdate(
fn: () => void,
dependencies?: any[]
): void
| Parameter | Description | Type | Default |
|---|---|---|---|
| fn | Callback function executed on update | () => void | - |
| dependencies | Dependency array | any[] | undefined |
Return Value
No return value.
Difference from useEffect
| Feature | useDidUpdate | useEffect |
|---|---|---|
| Initial mount | ❌ Does not execute | ✅ Executes |
| On update | ✅ Executes | ✅ Executes |
| Use case | Only care about updates | Care about mount and updates |
Notes
- Callback is not executed on initial component mount
- Only executes when dependencies change
- If no dependency array is passed, executes on every update
- Avoid modifying dependency values inside the callback, which may cause infinite loops
Usage Scenarios
- Data Synchronization: Sync to external systems when state changes
- Form Validation: Execute validation when fields change
- Logging: Record value changes
- Side Effects: Respond to specific state changes
- API Calls: Re-fetch data when search term changes