개인의 기록
  • 소개
  • 프로젝트
  • 글
  • 링크

© 2026 newgirok

← 글 목록

Controlled / Uncontrolled Component — 폼 데이터 관리 방식

2026년 5월 14일
React폼ControlledUncontrolled

React에서 폼(Form) 요소를 다루는 방식은 크게 두 가지로 나뉩니다. 데이터를 React 상태(state)로 관리하는 Controlled Component와, DOM이 직접 데이터를 보관하고 필요할 때 ref로 읽어오는 Uncontrolled Component입니다. 두 방식은 철학이 다르며, 상황에 따라 적합한 선택이 달라집니다.

Controlled Component

Controlled Component는 입력값을 React 상태로 관리합니다. 사용자가 입력할 때마다 이벤트 핸들러가 호출되고, 상태가 업데이트되며, 업데이트된 상태가 다시 입력 요소의 값으로 반영됩니다. React가 폼 데이터의 "단일 진실 공급원(Single Source of Truth)"이 됩니다.

단일 진실 공급원(Single Source of Truth): 데이터가 오직 한 곳에서만 관리되어 일관성을 보장하는 설계 원칙.

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

  return (
    <input
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  );
}
사용자 입력
    │
    ▼
onChange 이벤트
    │
    ▼
setState 호출
    │
    ▼
리렌더링 → input value 갱신

Controlled Component의 장점은 React 상태와 UI가 항상 동기화된다는 것입니다. 입력값을 실시간으로 검증하거나, 조건에 따라 입력을 차단하거나, 다른 컴포넌트와 상태를 공유하는 작업이 자연스럽게 처리됩니다. 단점은 모든 키 입력마다 상태 업데이트와 리렌더링이 발생한다는 것입니다. 폼 필드가 많고 입력 빈도가 높은 경우 성능에 영향을 줄 수 있습니다.

Uncontrolled Component

Uncontrolled Component는 폼 데이터를 DOM이 직접 보관합니다. React는 초기값만 설정하고(defaultValue), 실제 값은 필요한 시점에 ref를 통해 DOM에서 직접 읽어옵니다.

ref: React에서 DOM 요소나 컴포넌트 인스턴스에 직접 접근하기 위한 참조 객체.

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

  function handleSubmit() {
    console.log(inputRef.current.value);
  }

  return (
    <>
      <input ref={inputRef} defaultValue="" />
      <button onClick={handleSubmit}>제출</button>
    </>
  );
}
사용자 입력
    │
    ▼
DOM이 값 보관
(React 관여 없음)
    │
    ▼ (제출 시점)
ref.current.value로 읽기

Uncontrolled Component의 장점은 키 입력마다 리렌더링이 발생하지 않아 성능 부담이 적다는 것입니다. 또한 파일 업로드(<input type="file">)처럼 React 상태로 다루기 어려운 요소를 처리할 때 필수적입니다. 단점은 실시간 검증이나 조건부 비활성화처럼 입력 흐름을 제어하는 작업이 까다롭다는 것입니다.

장단점 비교

항목ControlledUncontrolled
데이터 위치React stateDOM
실시간 검증쉬움어려움
리렌더링 횟수키 입력마다제출 시점만
코드 양상대적으로 많음상대적으로 적음
파일 입력불가가능

선택 기준

실시간 피드백(입력 검증, 글자 수 카운트, 조건부 버튼 활성화)이 필요하거나, 다른 컴포넌트와 상태를 공유해야 한다면 Controlled Component가 적합합니다.

반면, 제출 시점에만 값이 필요하고 중간 상태 추적이 불필요한 단순한 폼이라면 Uncontrolled Component가 코드를 더 단순하게 만들어 줍니다. 파일 업로드는 항상 Uncontrolled 방식으로 처리해야 합니다.

대부분의 React 애플리케이션에서는 Controlled Component가 권장되는 기본값입니다. React의 선언형 데이터 흐름을 활용하면 상태와 UI 간의 불일치로 인한 버그를 방지할 수 있기 때문입니다. 단, 성능이 중요한 대규모 폼이나 라이브러리(React Hook Form 등)를 도입할 경우에는 Uncontrolled 방식을 기반으로 구현된 경우가 많으므로 두 개념을 모두 이해하고 있어야 합니다.

← 이전 글Ref — DOM과 값을 직접 참조하는 방법
다음 글 →Memoization — 불필요한 렌더링을 줄이는 최적화