Understanding Controlled and Uncontrolled Components in React

Frontend developer who weaves creativity and code, book lover, avid traveller and a tech enthusiast
Handling form is an integral part in React as most web apps rely a lot on the user input. React provides two approaches of handling form. They are via:
Controlled component
Uncontrolled component
Each method has their own pros and cons. Lets discuss them now
π Controlled Component
A component is called controlled when it is entirely controlled by Reactβs state.
Read more about state on this link
For example: whenever we create any input field or text area, their value comes from state.
When state changes, a component re-renders. As a result, we get the updated value.
β When to use
You are working on a complex form.
You want proper validations.
β When not to use
You have a simple form.
You have single input fields or very few input fields.
π₯ Benefits of controlled component
Since value is controlled by state, we have full control.
Immediate access to the form data and proper validation.
π Example
import { useState } from "react";
const Controlled = () => {
const [formData, setFormData] = useState({
firstName: "",
lastName: "",
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prev) => ({
...prev,
[name]: value,
}));
};
const handleSubmit = (e) => {
e.preventDefault();
console.log(formData);
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="firstName"
value={formData.firstName}
onChange={handleChange}
placeholder="Enter first name"
/>
<input
type="text"
name="lastName"
value={formData.lastName}
onChange={handleChange}
placeholder="Enter last name"
/>
<button type="submit">Submit</button>
</form>
);
};
export default Controlled;
π Uncontrolled Component
A component is called uncontrolled when the forms are handled by the DOM itself, not the React state.
Unlike controlled components, where form data is managed through React state and updated via setState, ref is used to access the input elements.
Unlike state, the component does not re-render when used ref as it remembers the past value.
β When to use
You have a small form with few inputs.
When you are working with non-React code.
β When not to use
You have complex forms.
You want full control and validation.
π₯ Benefits of uncontrolled component
Requires less code than controlled component.
They also perform better and feel more natural to React beginners who are familiar with HTML.
π Example
import { useRef } from "react";
const Uncontrolled = () => {
const fnameRef = useRef(null);
const lnameRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
const firstName = fnameRef.current?.value;
const lastName = lnameRef.current?.value;
console.log("Form data", firstName, lastName);
};
return (
<form className="controlled" onSubmit={handleSubmit}>
<h2>Uncontrolled approach</h2>
<input type="text" ref={fnameRef} placeholder="Enter first name" />
<input type="text" ref={lnameRef} placeholder="Enter last name" />
<button type="submit">Submit</button>
</form>
);
};
export default Uncontrolled;
β¨ Conclusion
In a nutshell, use controlled approach when you have a complex dynamic form and need more control. Use uncontrolled approach when you are dealing with a simple form.



