What are uncontrolled components?
In React, uncontrolled components are form elements whose state is managed by the DOM itself, rather than by React. This approach mirrors how traditional HTML forms function, where form data is accessed directly from the DOM when submitted.
What are Uncontrolled Components?
An uncontrolled component is a form input element (like <input>, <textarea>, or <select>) where the current value of the input is handled by the DOM. Instead of writing an event handler for every state update, you access the form's value directly when you need it, typically through a React Ref.
This means React doesn't control the input's value as it changes. When you need to get the value, you 'ask' the DOM for it, often upon form submission.
How They Work
To use an uncontrolled component effectively, you generally follow these steps:
- Create a Ref using
React.useRef()(for functional components) orReact.createRef()(for class components). - Attach this Ref to the form input element using the
refprop. - When you need to access the input's value (e.g., on form submission), use the Ref's
current.valueproperty to retrieve it from the DOM.
When to Use Uncontrolled Components
- For simple forms where you only need to get the final value upon submission, and don't require real-time validation or manipulation.
- When integrating with non-React code or legacy systems that expect direct DOM interaction.
- For specific cases where performance might be a concern due to frequent re-renders (though this is often negligible for most forms).
Example
Here's an example of an uncontrolled input field in a functional React component:
import React, { useRef } from 'react';
function NameForm() {
const nameInputRef = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
alert('A name was submitted: ' + nameInputRef.current.value);
};
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" ref={nameInputRef} defaultValue="Bob" />
</label>
<button type="submit">Submit</button>
</form>
);
}
export default NameForm;
In this example:
nameInputRefis created usinguseRef().- It's attached to the
<input>element viaref={nameInputRef}. - The
defaultValueprop is used to set the initial value. For uncontrolled components,defaultValue(ordefaultCheckedfor checkboxes,defaultSelectedfor select options) is used instead ofvalue. - When the form is submitted,
handleSubmitaccesses the input's value directly from the DOM usingnameInputRef.current.value.
Pros and Cons
| Pros | Cons |
|---|---|
| Simpler to implement for basic forms, especially if initial state doesn't need to be managed by React. | Less control over the input's state from within React. Real-time validation, formatting, or conditional disabling becomes harder. |
| Can be useful for integrating with external DOM manipulation libraries or legacy code. | Harder to reset the form programmatically or apply complex input logic. |
| Potentially fewer re-renders as React is not constantly updating state for every keystroke. | Can be less declarative, as you're reaching into the DOM directly. |
While uncontrolled components offer a simpler setup for very basic use cases, controlled components are generally preferred in React applications due to the greater control, predictability, and easier implementation of features like validation, instant feedback, and form resetting.