gotchajavascriptreactModerate
React controlled vs uncontrolled input warning
Viewed 0 times
controlled inputuncontrolled inputinput warningform stateundefined value
browser
Error Messages
Problem
React warns: 'A component is changing an uncontrolled input to be controlled.' This happens when an input starts with undefined value and later gets a defined value, or vice versa.
Solution
Ensure the value is never undefined:
// BAD: value starts as undefined
const [name, setName] = useState(); // undefined
<input value={name} /> // uncontrolled → controlled when name is set
// GOOD: initialize with empty string
const [name, setName] = useState('');
<input value={name} onChange={e => setName(e.target.value)} />
// For checkboxes
const [checked, setChecked] = useState(false); // not undefined
<input type='checkbox' checked={checked} onChange={e => setChecked(e.target.checked)} />
// Fallback for possibly undefined values
<input value={name ?? ''} onChange={...} />
<input value={name || ''} onChange={...} />
// BAD: value starts as undefined
const [name, setName] = useState(); // undefined
<input value={name} /> // uncontrolled → controlled when name is set
// GOOD: initialize with empty string
const [name, setName] = useState('');
<input value={name} onChange={e => setName(e.target.value)} />
// For checkboxes
const [checked, setChecked] = useState(false); // not undefined
<input type='checkbox' checked={checked} onChange={e => setChecked(e.target.checked)} />
// Fallback for possibly undefined values
<input value={name ?? ''} onChange={...} />
<input value={name || ''} onChange={...} />
Why
React has two modes for inputs: controlled (value prop set) and uncontrolled (no value prop, or value=undefined). Switching between modes during the component lifecycle causes unpredictable behavior. React warns because it can't tell if this was intentional.
Gotchas
- null and undefined both make an input uncontrolled — use empty string ''
- defaultValue is for uncontrolled inputs only — don't mix with value
- Textarea and select follow the same controlled/uncontrolled rules
- react-hook-form uses uncontrolled inputs by default (refs, not state)
Code Snippets
Properly initialized form state
// Always initialize form state with defined values
const [form, setForm] = useState({
name: '', // not undefined
email: '', // not undefined
agreed: false, // not undefined
});Context
When building forms in React with controlled inputs
Revisions (0)
No revisions yet.