controlled vs uncontrolled 컴포넌트 — React 폼 입력을 어떻게 다뤄야 하는가

controlled 컴포넌트와 uncontrolled 컴포넌트의 차이, 각각의 장단점, 그리고 언제 어떤 방식을 선택하면 좋은지 React 폼 예제로 설명한다.

Seobway · · 10분

이 시리즈 구성

포스트 내용
로드맵 인덱스 → 01~19 전체 학습 경로
01-1. JS 이벤트 루프와 비동기 → 콜스택, 큐, 마이크로태스크
01-2. setTimeout vs Promise → 비동기 실행 순서 예측
01-3. React 단방향 데이터 흐름 → props/state, state 끌어올리기
01-4. controlled vs uncontrolled → React 폼 설계
01-5. TypeScript 타입 시스템 기초 → any, unknown, union, narrowing

왜 폼에서 갑자기 복잡해지는가

React 초반에 많이 헷갈리는 지점이 폼이다.

입력값 하나만 받아도 곧바로 이런 고민이 생긴다.

이때 나오는 두 가지 방식이 controlleduncontrolled 다.


controlled 컴포넌트

controlled 컴포넌트는 입력값의 현재 상태를 React state가 소유하는 방식이다.

function SignupForm() {
  const [email, setEmail] = useState('')

  return (
    <input
      value={email}
      onChange={(e) => setEmail(e.target.value)}
    />
  )
}

여기서는 input의 실제 값과 React state가 항상 같이 움직인다.

장점

단점


uncontrolled 컴포넌트

uncontrolled 컴포넌트는 입력값을 DOM이 들고 있고, 필요할 때만 읽는 방식이다.

function SignupForm() {
  const emailRef = useRef<HTMLInputElement>(null)

  function handleSubmit(e: React.FormEvent) {
    e.preventDefault()
    console.log(emailRef.current?.value)
  }

  return (
    <form onSubmit={handleSubmit}>
      <input ref={emailRef} defaultValue="" />
      <button type="submit">전송</button>
    </form>
  )
}

여기서는 React state가 아니라 input DOM이 값을 들고 있다.

장점

단점


어떤 상황에서 무엇을 선택할까

controlled가 잘 맞는 경우

uncontrolled가 잘 맞는 경우

%% desc: 입력 중 상태를 계속 써야 하면 controlled, 제출 시점에만 읽으면 uncontrolled가 잘 맞는다
flowchart TD
  Q["입력 중 값을 계속 써야 하는가?"] -->|예| C["controlled"]
  Q -->|아니오| U["uncontrolled"]
  C --> C1["실시간 검증\n조건부 버튼 상태\n미리보기"]
  U --> U1["간단 폼\n파일 입력\n제출 시점 읽기"]

React Hook Form이 인기 있는 이유

폼 라이브러리를 배우다 보면, 왜 React Hook Form이 자주 언급되는지 이해하게 된다.

이 라이브러리는 기본적으로 uncontrolled 성격을 활용하면서도, 검증과 에러 관리 같은 개발 편의를 잘 붙여 준다. 즉 controlled와 uncontrolled의 trade-off를 실무 친화적으로 풀어낸 셈이다.


실무에서는 이렇게 생각하면 편하다


마치며

controlled와 uncontrolled는 둘 중 하나만 옳은 문제가 아니다.

중요한 것은 다음 질문이다.

그 기준이 분명하면 폼 설계도 훨씬 단순해진다.

조금 더 깊게 보기

폼은 상태 동기화 문제다

폼은 단순한 input 모음이 아니다. 사용자는 한 글자씩 입력하고, UI는 검증하고, 버튼 상태를 바꾸고, 에러 메시지를 보여준다. 그래서 폼은 화면과 데이터가 계속 왕복하는 상태 동기화 문제다.

controlled의 진짜 의미

controlled 컴포넌트는 React가 입력값의 원본이 되는 방식이다. 비밀번호 강도 표시, 실시간 검색, 제출 버튼 활성화처럼 입력 중 값이 다른 UI에 영향을 주는 경우에 강력하다.

uncontrolled가 실무에서 사라지지 않는 이유

제출 시점에만 값이 필요하거나 파일 input처럼 DOM API가 중심인 경우에는 uncontrolled가 더 단순하다. React Hook Form 같은 라이브러리가 uncontrolled 성격을 활용하는 것도 이 때문이다.


참고

  1. [1] React Docs — input
  2. [2] React Docs — Referencing Values with Refs

관련 글