React - Forms & Controlled Components
Controlled Inputs
In a controlled component, form values are driven by React state.
Try it: Name Form
View source
const { useState } = React;
function NameForm(){
const [name, setName] = useState('');
return (
<form onSubmit={e => { e.preventDefault(); alert(`Hello ${name}`); }}>
<label>
Name: <input value={name} onChange={e => setName(e.target.value)} />
</label>
<button type="submit" style={{marginLeft:8}}>Greet</button>
</form>
);
}
ReactDOM.createRoot(document.getElementById('try-forms')).render(<NameForm />);
Syntax primer (for newcomers)
- Controlled input:
<input value={name} onChange={e => setName(e.target.value)} />
- For checkboxes use
checked
ande.target.checked
. - Prevent default form submit with
e.preventDefault()
.
More examples
Controlled select and checkbox:
View source
const { useState } = React;
function PreferenceForm(){
const [lang, setLang] = useState('js');
const [agree, setAgree] = useState(false);
return (
<form onSubmit={e => { e.preventDefault(); alert(`${lang} / ${agree}`); }}>
<label>Language: <select value={lang} onChange={e => setLang(e.target.value)}>
<option value="js">JavaScript</option>
<option value="ts">TypeScript</option>
</select></label>
<label style={{marginLeft:8}}>
<input type="checkbox" checked={agree} onChange={e => setAgree(e.target.checked)} /> Agree
</label>
<button style={{marginLeft:8}}>Save</button>
</form>
);
}
ReactDOM.createRoot(document.getElementById('try-forms-2')).render(<PreferenceForm />);
Vocabulary
- Controlled component: Form input whose value is driven by React state.
- Uncontrolled component: Form input that manages its own state in the DOM.
Common pitfalls
- Mixing controlled and uncontrolled inputs causes warnings; once you add
value
, keep it controlled. - Checkboxes use
checked
andonChange
withe.target.checked
—notvalue
. - For non-submit buttons inside forms, set
type="button"
to avoid accidental submit.
Exercises
- Add length validation (min 3 chars) and show an inline error message while typing.
- Add a required agreement checkbox; disable the submit button until it’s checked.
- Split the name into first and last fields and show a computed full name preview.