Uncontrolled Components
An uncontrolled component lets the DOM maintain an input's current value instead of storing that value in React state. React typically reads the value when needed through a ref, making this approach useful for simple forms and DOM-oriented integrations.
In an uncontrolled component, the input element is the source of truth for its current value. You provide an initial value with `defaultValue` or `defaultChecked`, rather than continuously passing a `value` prop from React state.
A ref gives React code access to the underlying DOM element. For example, a form can read `inputRef.current.value` when the user submits it. React does not need to re-render on every keystroke just to keep a state variable synchronized.
This differs from a controlled component, where React state owns the current value and the input receives that value through `value`. Controlled inputs are generally preferable when the UI must react immediately to every edit, such as validation, conditional fields, or formatting.
Uncontrolled inputs can be convenient when the form is straightforward or when integrating with APIs that expect direct DOM access. They can also reduce the amount of state-management code, but validation and synchronization logic may be less centralized.
Key points
- The DOM is the source of truth for the current input value.
- Use refs to read an uncontrolled input when needed.
- Use `defaultValue` or `defaultChecked` for the initial value.
- Avoid switching an input between controlled and uncontrolled modes.
- Controlled components are better when React must respond to every edit.
Interview questions
What is an uncontrolled component in React?
An uncontrolled component is a form element whose current value is maintained by the DOM rather than React state. React can access that value through a ref when it needs it. The initial value can be supplied with `defaultValue` or `defaultChecked`. This is different from a controlled input, where React state is the source of truth.
How do you read the value of an uncontrolled input?
Create a ref with `useRef` and attach it to the input using the `ref` prop. When the value is needed, read `ref.current.value`, typically inside an event handler such as form submission. The ref points to the underlying DOM element after it has mounted.
What is the difference between `defaultValue` and `value`?
`defaultValue` sets the initial value of an uncontrolled input, while `value` specifies its current value from React. An input using `value` normally needs an `onChange` handler to update the corresponding state. Changing `defaultValue` after the initial setup does not provide the same ongoing synchronization as `value`.
When would you choose an uncontrolled component instead of a controlled one?
An uncontrolled component can be a good fit for simple forms where React does not need to respond to every keystroke. It is also useful when code needs direct interaction with the DOM or when integrating with APIs built around native form elements. A controlled component is usually more appropriate when validation, conditional rendering, formatting, or other React state must immediately depend on the current input.
What problem occurs if an input switches between controlled and uncontrolled?
React expects an input to have a consistent ownership model during its lifetime. Switching between an uncontrolled input and a controlled input can produce warnings and confusing synchronization behavior. This commonly happens when a controlled value starts as `undefined` and later becomes a string. Initializing state consistently, or deliberately choosing one model, avoids the problem.