BioPlayground

🧬
목록으로

Controlled vs Uncontrolled — 폼 입력 다루기

React에서 폼 입력을 다루는 Controlled와 Uncontrolled 패턴의 차이, 각각의 장단점, 선택 기준을 설명합니다.

중급
|
5
|
검증 완료 (2026-07)
진행률0/55 (0%)

Controlled vs Uncontrolled — 폼 입력 다루기

이 토픽을 마치면

React에서 input을 다루는 두 가지 방식의 차이를 이해하고, 상황에 맞게 선택할 수 있게 됩니다.


HTML의 기본 동작

HTML의 input은 자체적으로 값을 관리합니다:

html
<input type="text" />

사용자가 입력하면 input 자체가 값을 보관합니다. JavaScript가 관여하지 않아도 동작합니다.

React에서는 이 값을 React가 관리할지, input이 스스로 관리하게 둘지 선택합니다.


Controlled: React가 관리

jsx
function SearchBox() {
  const [query, setQuery] = useState("");

  return (
    <input
      value={query}
      onChange={(e) => setQuery(e.target.value)}
    />
  );
}

value를 state로 지정하고, onChange로 state를 업데이트합니다. 사용자가 타이핑할 때마다:

  1. onChange 이벤트 발생
  2. setQuery로 state 변경
  3. 리렌더링
  4. input에 새 값 반영

React가 input의 값을 통제합니다. 그래서 "Controlled"입니다.

장점: 입력값에 대한 완전한 제어. 실시간 유효성 검사, 입력 제한, 포맷팅이 가능합니다.

jsx
function PhoneInput() {
  const [phone, setPhone] = useState("");

  const handleChange = (e) => {
    const cleaned = e.target.value.replace(/\D/g, "");
    if (cleaned.length <= 11) {
      setPhone(cleaned);
    }
  };

  return <input value={phone} onChange={handleChange} />;
}

숫자만 입력되고 11자리를 넘길 수 없습니다.


Uncontrolled: DOM이 관리

jsx
function FileUpload() {
  const inputRef = useRef(null);

  const handleSubmit = () => {
    const file = inputRef.current.files[0];
    console.log(file.name);
  };

  return (
    <div>
      <input type="file" ref={inputRef} />
      <button onClick={handleSubmit}>Upload</button>
    </div>
  );
}

ref로 DOM 요소에 직접 접근해서 값을 읽습니다. React state를 거치지 않습니다. input 자신이 값을 관리하고, 필요할 때만 읽습니다.

파일 input은 보안상 value를 프로그래밍으로 설정할 수 없어서, uncontrolled로 쓸 수밖에 없습니다.


선택 기준

Controlled를 쓸 때:

  • 실시간 유효성 검사 (이메일 형식 확인, 글자 수 제한)
  • 입력값에 따라 다른 UI를 즉시 보여줘야 할 때
  • 여러 input의 값을 하나의 state로 관리할 때
  • 폼 제출 전에 데이터를 가공해야 할 때

Uncontrolled를 쓸 때:

  • 파일 업로드
  • 값을 제출 시점에만 읽으면 될 때
  • 기존 HTML 폼을 React로 마이그레이션할 때

대부분의 경우 Controlled가 기본 선택입니다. React 공식 문서도 Controlled를 권장합니다.


핵심

Controlled 컴포넌트는 React state가 input 값을 관리합니다. 실시간 제어가 가능합니다. Uncontrolled 컴포넌트는 DOM이 값을 관리하고, ref로 필요할 때 읽습니다. 대부분의 폼에서 Controlled가 기본 선택입니다.