Skip to main content

How is an "Uncontrolled Component" different?

Definition

An Uncontrolled Component is a component that keeps its own state (for example, an input field's value) inside the DOM, rather than in React state (useState).

React does not manage its value directly here - it simply reads it when needed (via a ref or on form submit).


Example of an uncontrolled component

javascript
function LoginForm() { const emailRef = useRef(); const passwordRef = useRef(); function handleSubmit(e) { e.preventDefault(); console.log({ email: emailRef.current.value, password: passwordRef.current.value, }); } return ( <form onSubmit={handleSubmit}> <input ref={emailRef} type="email" placeholder="Email" /> <input ref={passwordRef} type="password" placeholder="Password" /> <button type="submit">Log in</button> </form> ); }

Here:

  • the <input> stores its own value (inside the DOM);
  • React doesn't know what the user is typing;
  • on submit, we pull the value out of the DOM via ref.

Difference from a controlled component

Controlled Component

javascript
function Controlled() { const [name, setName] = useState(''); return ( <input value={name} onChange={(e) => setName(e.target.value)} // React controls the value /> ); }

React is the "single source of truth".


Uncontrolled Component

javascript
function Uncontrolled() { const inputRef = useRef(); return ( <input ref={inputRef} /> // the value lives in the DOM ); }

The DOM is the source of truth, React just observes.


Key differences

CriterionControlledUncontrolled
Where the value is storedIn React stateInside the DOM
How it's updatedVia onChange -> setStateThe user types directly
Does React know the current value?YesNo (until requested via ref)
Data managementFully controlled by ReactReact "asks" the DOM when needed
Validation / masks / autofillPossible in real timeOnly on submit
Convenience for complex formsHighLimited
PerformanceSlightly lower (frequent renders)Slightly higher (React doesn't track every change)

When to use Uncontrolled Components

They fit simple, isolated forms that don't need an instant reaction to input. For example:

  • a subscription form with one field and a button;
  • a search box where the value is read only on submit;
  • integration with third-party libraries that manage the DOM themselves (input[type=file], third-party widgets, etc.).

A real-world example (input type="file")

javascript
function FileUploader() { const fileRef = useRef(); function handleUpload() { const file = fileRef.current.files[0]; console.log(file.name); } return ( <div> <input type="file" ref={fileRef} /> {/* React does not manage this */} <button onClick={handleUpload}>Upload</button> </div> ); }

<input type="file" /> is always uncontrolled, because React has no direct access to file data. Here the DOM controls the value.


Sometimes you can mix the two

Sometimes a hybrid approach is convenient:

  • set an initial value on mount;
  • don't manage it through state afterward.
javascript
<input defaultValue="Hello" /> // Uncontrolled with initial data

The defaultValue attribute (or defaultChecked) sets the starting value, but after that React doesn't track changes.


Summary

PropertyControlled ComponentUncontrolled Component
Source of truthReact stateDOM
Input managementReact controls itThe browser controls it
Reading the valueVia stateVia ref
Reaction to changesIn real timeOnly on an event
Use caseComplex forms, validation, dynamic behaviorSimple forms, integrations, <input type="file">
Attributesvalue, onChangedefaultValue, ref

Main idea: A controlled component: React "holds the wheel". An uncontrolled one: "the browser drives itself", and React just watches.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.