A controlled input gets its value from React state. An uncontrolled input keeps its own value in the DOM.
Controlled: you pass the value through the value (or checked) prop. The input reports changes through onChange, which updates state. React state is the single source of truth. So you can validate on every keystroke, format the input, or disable a button based on the current value.
Uncontrolled: you set the starting value with defaultValue. You read the current value when you need it, through a ref or from FormData on submit. It needs less code and causes fewer re-renders.
Use controlled inputs when the UI must react to the value as it changes. Uncontrolled inputs work well for simple forms, especially with React 19 form actions that receive FormData.
Do not switch an input between the two. For example, if value goes from undefined to a string, React shows a warning.
- Controlled inputs use
valueplusonChange, and React state is the source of truth. - Uncontrolled inputs keep the value in the DOM and use
defaultValuefor the starting value. - Read uncontrolled values with refs or
FormData. - Controlled inputs make live validation and formatting possible.
- Do not switch an input between controlled and uncontrolled.