What are controlled and uncontrolled components in React?

👨‍💻 Frontend Developer 🟠 May come up 🎚️ Medium
#React

Brief Answer

Controlled components — React controls the element form value 💼 Uncontrolled components — DOM controls the element form value 🆓

// Controlled — value through state
<input value={value} onChange={handleChange} />
 
// Uncontrolled — value directly from DOM
<input defaultValue="text" ref={inputRef} />

Full Answer

Controlled and uncontrolled components — like the difference between a trained and a wild horse! 🐎

Controlled Components — Under Control

Controlled components — like manual mode in a video game: you control everything yourself:

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

How it works:

  1. Value stored in React state
  2. On change — handler called
  3. Handler updates state
  4. Component re-renders with new value

Uncontrolled Components — Freedom

Uncontrolled components — like autopilot: browser controls itself, you just observe:

function UncontrolledForm() {
  const inputRef = useRef();
  
  return <input defaultValue="initial value" ref={inputRef} />;
}

How it works:

  1. Value stored in DOM element
  2. React doesn’t control the value
  3. Access through ref only when needed

When to Use What

Controlled — for most cases

// ✅ Forms with validation
// ✅ Instant checking
// ✅ Complex interactions
// ✅ Testing
 
<input value={email} onChange={handleEmailChange} />

Uncontrolled — for simple cases

// ✅ Simple forms
// ✅ Integration with non-React code
// ✅ When no real-time control needed
 
<input defaultValue={name} ref={nameRef} />

Practical Differences

Controlled

// Full control
const [text, setText] = useState('');
 
// Can check every character
const handleChange = (e) => {
  const value = e.target.value;
  // Check: only letters
  if (/^[a-zA-Z]*$/.test(value)) {
    setText(value);
  }
};
 
<input value={text} onChange={handleChange} />

Uncontrolled

// Minimal code
const inputRef = useRef();
 
// Get value only on submit
const handleSubmit = () => {
  console.log(inputRef.current.value);
};
 
<input defaultValue="text" ref={inputRef} />

Common Mistakes

Mixing Approaches

// ❌ Mistake — mixing value and defaultValue
<input value={name} defaultValue="text" /> // Conflict!
 
// ✅ Correct — choose one approach
<input value={name} onChange={handleChange} /> // Controlled
// or
<input defaultValue={name} ref={inputRef} /> // Uncontrolled

Forgetting about ref

// ❌ Mistake — trying to get uncontrolled component value
function Form() {
  // No ref!
  return <input defaultValue="text" />;
  
  // How to get value? Impossible!
}
 
// ✅ Correct — use ref
function Form() {
  const inputRef = useRef();
  return <input defaultValue="text" ref={inputRef} />;
}

Simple Rules

  1. Controlled — value through state, full control 💼
  2. Uncontrolled — value in DOM, freedom 🆓
  3. Controlled — for forms with validation ✅
  4. Uncontrolled — for simple cases 🚀
  5. Don’t mix — choose one approach per component ⚠️
  6. ref for uncontrolled — how to get value 🎯

Understanding the difference between controlled and uncontrolled components helps build forms correctly in React! 💪


Want more articles to prepare for interviews? Subscribe to EasyAdvice, bookmark the site and improve yourself every day 💪