Events and forms
Control an input with state
Make React state the current source of truth by pairing the input value with an onChange handler.
A controlled input gets its current value from React state.
function TaskForm() {
const [title, setTitle] = useState('')
return (
<label>
Task title
<input
name="title"
value={title}
onChange={event => setTitle(event.target.value)}
/>
</label>
)
}
Type Buy milk and the input shows exactly that text on every keystroke.
Each edit follows the React cycle:
- The browser reports the edit and React calls the
onChangehandler. - The handler requests a state update.
- React renders with the new
title. - The input receives that value.
State is the source of truth. This makes it easy to display a character count, format a value, or disable submission according to the same data.
Do not pass value without onChange unless the input is intentionally read-only. React will keep restoring the prop value, so typing appears broken.
Initialize text inputs with a string, usually ''. Switching between undefined and a string changes between uncontrolled and controlled behavior and produces warnings in the console.
Controlling every keystroke causes the owner component to render. Keep state close to the form so unrelated expensive sections do not rerender. Optimize only after measuring a real problem.
Checkboxes and selects follow the same pattern: pass checked or value from state and update state in onChange. The browser still fires the events, but React decides what the control shows next.
Textareas and selects use the same controlled pattern with value and onChange. The DOM element type changes, but the data flow does not.
Reset a controlled field by updating state, not by reaching into the DOM. setTitle('') clears the input because the next render passes an empty string.
Add a live character count and confirm the input, count, and state always agree.
Lesson completed