비제어 입력에서는 defaultValue로 초기값만 주고 이후 값은 DOM이 관리합니다. React 상태를 매 키 입력마다 바꾸지 않아도 됩니다.
데모는 입력 필드가 먼저 변하고 제출 순간에만 결과가 갱신되는 차이를 보여줍니다. 입력 중 다른 UI가 값에 반응해야 한다면 제어 입력이 더 단순합니다.
언제 쓰나
제출 시점의 값만 필요한 간단한 폼이나 기존 DOM 중심 코드와 연동할 때 적합합니다.
입력 중 값은 DOM이 보관하고, 제출할 때 ref나 FormData로 읽습니다.
<div class="scene"><div class="title">DOM owns the draft</div><div class="columns"><div class="pill">input<br><strong id="draft">A</strong></div><div class="button" id="submit">SEND</div><div class="pill">read at submit<br><strong id="saved">—</strong></div></div><div class="meter"><span id="meter"></span></div></div>.scene{width:min(94vw,800px);height:min(86vh,320px);position:relative;overflow:hidden;display:flex;flex-direction:column;justify-content:space-between;border:1px solid var(--line);border-radius:14px;background:var(--surface);padding:clamp(9px,2.4vmin,20px);font:500 clamp(15px,4vmin,18px)/1.3 var(--font-sans,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif)}.scene b,.scene strong{font-weight:700}.label{color:var(--muted)}.code{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}.pill{border:1px solid var(--line);border-radius:8px;padding:.4em .65em;background:var(--bg)}.active{border-color:var(--accent)!important;color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 10%,var(--surface))!important}.title{color:var(--accent);font-weight:700}.columns{height:65%;display:flex;align-items:center;justify-content:space-around;gap:6px;text-align:center}.columns .pill{width:36%;height:55%;display:flex;flex-direction:column;justify-content:center}.columns strong{font:700 clamp(18px,6vmin,34px) ui-monospace,monospace;color:var(--accent)}.button{min-width:58px;border-radius:8px;padding:.5em;background:var(--accent);color:var(--bg);font:700 clamp(12px,3vmin,15px) ui-monospace,monospace}.meter{height:4px;background:var(--line)}.meter span{display:block;height:100%;width:0;background:var(--accent);transition:width .4s}let i=0;const data=["A","AB","ABC","ABCD"];function tick(){document.getElementById("draft").textContent=data[i%4];const send=i%4===3;document.getElementById("submit").style.opacity=send?1:.55;if(send)document.getElementById("saved").textContent=data[i%4];document.getElementById("meter").style.width=((i%4+1)*25)+"%";i++}tick();setInterval(tick,750)비제어 입력에서는 defaultValue로 초기값만 주고 이후 값은 DOM이 관리합니다. React 상태를 매 키 입력마다 바꾸지 않아도 됩니다.
데모는 입력 필드가 먼저 변하고 제출 순간에만 결과가 갱신되는 차이를 보여줍니다. 입력 중 다른 UI가 값에 반응해야 한다면 제어 입력이 더 단순합니다.
제출 시점의 값만 필요한 간단한 폼이나 기존 DOM 중심 코드와 연동할 때 적합합니다.