Skip to main content

Controlled vs Uncontrolled Components

Controlled = React manages, Uncontrolled = DOM manages


Controlled Components

"React controls the value"

Controlled components have their value controlled by React state.

"Controlled components have their value controlled by React state, with React as the single source of truth."


Controlled Component Example

value + onChange = controlled

function ControlledInput() {
const [value, setValue] = useState("");

return <input value={value} onChange={(e) => setValue(e.target.value)} />;
}

"Controlled components use value prop and onChange handler, with state managing the input value."


Uncontrolled Components

"DOM manages the value"

Uncontrolled components let the DOM manage the value using refs.

"Uncontrolled components let the DOM manage the value, accessed via refs rather than React state."


Uncontrolled Component Example

ref to access DOM value

function UncontrolledInput() {
const inputRef = useRef(null);

const handleSubmit = () => {
console.log(inputRef.current.value);
};

return (
<>
<input ref={inputRef} />
<button onClick={handleSubmit}>Submit</button>
</>
);
}

"Uncontrolled components use refs to access DOM values, with the DOM as the source of truth."


When to Use Controlled

Need React state · Validation · Real-time updates

Use controlled when:

  • Need to validate on every keystroke
  • Need to format input
  • Need to disable submit based on value
  • Need to reset form programmatically

"Use controlled components when you need validation, formatting, or programmatic control over the input value."


When to Use Uncontrolled

Simple forms · File inputs · Performance

Use uncontrolled when:

  • Simple forms
  • File inputs (must be uncontrolled)
  • Performance matters (fewer re-renders)
  • Integrating with non-React code

"Use uncontrolled components for simple forms, file inputs, or when performance is critical."


File Inputs

File inputs must be uncontrolled

function FileInput() {
const fileRef = useRef(null);

const handleSubmit = () => {
const file = fileRef.current.files[0];
// Process file
};

return <input type="file" ref={fileRef} onChange={handleSubmit} />;
}

File inputs are read-only and must be uncontrolled.

"File inputs must be uncontrolled because they're read-only and React can't set their value."


Comparison

Controlled = more control, Uncontrolled = simpler

AspectControlledUncontrolled
Value sourceReact stateDOM
UpdatesonChange handlerDOM native
ValidationEasyManual
PerformanceMore re-rendersFewer re-renders
ComplexityMore codeLess code

"Controlled components offer more control and easier validation, while uncontrolled are simpler with better performance."


9️⃣ Hybrid Approach

Default value + ref

function HybridInput() {
const inputRef = useRef(null);

return (
<input
ref={inputRef}
defaultValue="initial"
onChange={() => {
// Access via ref when needed
console.log(inputRef.current.value);
}}
/>
);
}

Use defaultValue for initial value, ref for access.

"Hybrid approach uses defaultValue for initial value and refs for accessing current value."


Best Practices

✅ Use controlled for most forms ✅ Use uncontrolled for file inputs ✅ Use controlled when validation needed ✅ Use uncontrolled for simple, performance-critical inputs ✅ Prefer controlled for React integration


"Controlled components have values controlled by React state via value and onChange. Uncontrolled components let the DOM manage values, accessed via refs. Controlled offers more control and validation, uncontrolled is simpler with better performance. File inputs must be uncontrolled. Choose based on needs - controlled for validation, uncontrolled for simplicity."


🧠 Ultra-Short Cheat Sheet

Controlled = React state (value + onChange)
Uncontrolled = DOM (ref)
Controlled: validation, control
Uncontrolled: simple, performance
File inputs = uncontrolled
Choose based on needs