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 checkedande.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 checkedandonChangewithe.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.