Capítulo 98 de 116

Chapter 98: <input>

Core Idea

<input> is the canonical example of React's controlled vs. uncontrolled distinction: pass value + onChange and React owns the field's value (controlled); pass defaultValue and let the DOM manage it internally, reading it via a ref only when needed (uncontrolled) — mixing the two on the same input is an error.

Key Concepts

  • Controlled: <input value={text} onChange={e => setText(e.target.value)} /> — the displayed value is always exactly text; every keystroke goes through React state, letting you validate, transform, or restrict input in real time.
  • Uncontrolled: <input defaultValue={initialText} ref={inputRef} /> — the DOM manages the value itself after the initial render; React only reads it on demand via the ref (e.g. at form submission time via FormData, Ch 97).
  • Never pass both value and defaultValue — React warns, since they express contradictory ownership models for the same field.
  • A controlled input without an onChange handler is read-only and logs a warning — passing value alone (no way to update it) traps the field at its initial value, which is almost never intended.
  • Checkbox/radio use checked/defaultChecked instead of value/defaultValue, following the same controlled/uncontrolled split.
  • Type coercion caveat: <input type="number">'s value is still a string in e.target.value — convert explicitly (Number(e.target.value)) rather than assuming a numeric type.

Code Examples

// Controlled: React state is the single source of truth
<input value={query} onChange={e => setQuery(e.target.value)} />
  • What it demonstrates: the controlled pattern — every character typed flows through setQuery, so query always reflects exactly what's displayed.

Key Takeaways

  1. Pick controlled or uncontrolled per field and stay consistent — never mix value and defaultValue on the same element.
  2. A controlled input needs onChange, or it becomes effectively frozen/read-only.
  3. e.target.value is always a string, regardless of type — numeric inputs still need explicit conversion.

Connects To

  • Ch 15 (Passing Props to a Component): the props mechanism underlying value/onChange.
  • Ch 97 (<form>): how uncontrolled field values get read via FormData at submission.
  • Ch 62 (useRef): the ref-based read pattern for uncontrolled inputs.