- Home
- Javascript
- Controlled vs Uncontrolled Components
React Controlled vs Uncontrolled Components: Guide
Contents
Controlled vs Uncontrolled Components
What is an Uncontrolled Component?
An uncontrolled input keeps its own value in the DOM, like a normal HTML input. You read the value only when you need it, usually with a ref.
jsx
import { useRef } from "react";
function SearchForm() {
const inputRef = useRef(null);
function handleSubmit(event) {
event.preventDefault();
console.log(inputRef.current.value);
}
return (
<form onSubmit={handleSubmit}>
<input type="text" ref={inputRef} defaultValue="" />
<button type="submit">Search</button>
</form>
);
}useRef is covered properly in Module 7. For now, notice the difference: there is no value prop and no onChange. The input manages itself, and inputRef.current.value reads it on demand.
Comparison
Aspect | Controlled | Uncontrolled |
| Value stored in | React state | The DOM |
| Requires onChange | Yes | No |
| Initial value prop | value | defaultValue |
| Live validation | Easy | Difficult |
| Re-renders while typing | Yes, on every keystroke | No |
| Reading the value | Directly from state | Via a ref, when needed |
| Recommended for | Most forms | File inputs, simple one-off forms, integrating non-React code |
Which Should You Use?
Use controlled components by default. The React documentation recommends them, and every feature beyond "collect the value once" is easier with them.
Use uncontrolled components in two situations:
- File inputs. <input type="file" /> is always uncontrolled — its value cannot be set programmatically for security reasons.
- Very large forms where re-rendering on every keystroke measurably hurts performance. This is rare, and you should measure before assuming it.
Mini-Project: Course Enrolment Form
What you will build
A multi-field enrolment form with validation and a live summary.
Requirements
- Fields: full name (text), email (email), phone (text), course (select), experience level (radio buttons), and a terms checkbox.
- Store all fields in a single state object with one shared change handler.
- Validate on submit: all fields required, email must contain @, phone must be exactly 10 digits, terms must be checked.
- Show each error message directly under its field.
- Disable the submit button while the terms checkbox is unchecked.
- On successful submission, show a summary card displaying everything the user entered, and clear the form.
Concepts used: controlled components, single-object form state, computed property names, radio and checkbox handling, validation, conditional rendering, event.preventDefault().
Expected outcome: a form that blocks invalid submissions with clear messages, and replaces itself with a confirmation summary when valid.
ReactJS Tutorial
Vishalini A








