FEInterview Prep

react · high priority

React Forms — Controlled vs Uncontrolled, React Hook Form, Zod

폼은 왜 그렇게 느려지는가 — re-render 비용을 0 으로 만드는 ref 기반 설계와 스키마 기반 검증

intermediate 난이도5시간토스카카오네이버배민당근라인
시작 전
이해도
매우 낮음

학습 개요

선행 학습

  • react-hooks-deep

탄생 배경

쉬운 설명

복잡한 개념을 실생활 비유로 설명합니다.

음식점 주문 — 키오스크 vs 종이 주문서

Controlled 폼은 손님이 메뉴를 한 번 누를 때마다 점원이 "지금까지 주문하신 게 김치찌개 한 개, 추가로 김치찌개 한 개..." 하고 전체 주문을 매번 재확인하는 키오스크입니다. 빠르게 누르면 점원이 따라오질 못해요. Uncontrolled 폼은 손님이 종이에 쭉 적다가 다 끝났다고 손을 들면 점원이 그때 한 번에 받아 적는 종이 주문서입니다. 점원 입장에서 일이 0 입니다 — 손님이 적는 동안엔. React Hook Form 은 이 종이 주문서 모델 위에서 추가로 "이 줄에 글씨가 잘못됐는지" 만 별도 검사관이 한 줄씩 본다는 식으로 검증을 분리한 것입니다.

핵심 개념

컴포넌트가 input 의 value 를 React state 로 들고 매 변경마다 setState 하면 **controlled**, 그냥 DOM 이 알아서 값을 들고 있고 우리는 ref 로 필요할 때 읽기만 하면 **uncontrolled** 다. 둘 중 어느 쪽이 옳은가가 아니라, **언제 어느 쪽이 적합한가** 가 질문이다.

Controlled vs Uncontrolled

Controlled (useState)
  • valueonChange 가 한 쌍 — React 가 진실의 원천
  • 키 입력마다 setState → 부모 트리 리렌더
  • 실시간 검증·포맷팅·다른 필드와의 동기화에 자연스러움
  • 필드 5~10개 짜리 작은 폼, 결제/검색바 등 즉시 반응 UI 에 적합
1const [name, setName] = useState('');
2return (
3 <input
4 value={name}
5 onChange={(e) => setName(e.target.value)}
6 />
7);
Uncontrolled (ref)
  • defaultValue 만 주고 값은 DOM 이 보유
  • 키 입력에 React 가 관여하지 않음 → 0 리렌더
  • 값이 필요할 때만 ref 로 읽음 (보통 submit 시점)
  • 큰 폼 전체에서 압도적으로 빠름. RHF 가 채택한 모델
1const ref = useRef<HTMLInputElement>(null);
2return (
3 <form onSubmit={() => console.log(ref.current?.value)}>
4 <input ref={ref} defaultValue="" />
5 </form>
6);

큰 폼에서 controlled 가 느린 진짜 이유

controlled 모델은 한 글자 입력마다 → setState → 폼 컴포넌트 리렌더 → 모든 자식 필드 리렌더 → 각 필드가 props 비교/스타일 재계산. 30 필드 + 각 필드에 select/checkbox 가 섞이면 한 입력에 수백 개의 가상 DOM 노드가 다시 만들어진다. React Profiler 에서 한 글자에 20-50ms 가 찍히는 게 이 패턴의 전형이다.

언제 어느 쪽?
상황권장이유
필드 5개 이내 + 실시간 동기화 필요Controlledstate 동기화 비용 < 코드 복잡도 절감
필드 20개 이상 결제/온보딩Uncontrolled (RHF)리렌더 비용이 폭발 → ref 기반이 압도적
검색바 + 디바운스 + 즉시 결과Controlled입력 자체가 검색 트리거
파일 업로드 / Date picker / Rich textUncontrolled복잡한 native 위젯과 ref 친화
서버 액션 form (Next 15)둘 다 가능progressive enhancement 가 우선이면 native form 유지

실무 적용

어떤 상황에서 사용하는가

결제 페이지가 입력할 때마다 한 글자씩 늦게 찍힌다는 리포트. 필드는 22개(주소·카드·할인코드·동의 체크 다수). 현재는 모든 필드가 useState 로 controlled.

어떻게 적용하는가

먼저 React Profiler 로 한 글자 입력에 commit 시간이 30-50ms 인 것을 확인. RHF 로 마이그레이션하되 한 번에 다 바꾸지 않고 가장 트래픽 높은 결제 폼부터 점진적으로 — useState 들을 useForm 의 register 로 교체, 기존 onSubmit 에 들어가던 검증 로직을 Zod 스키마로 뽑아 zodResolver 로 연결. 라이브러리 컴포넌트(Date picker 등) 만 Controller 로 감싸 controlled 로 둠. mode 는 onTouched 로 두어 첫 touch 후엔 즉시 피드백, 그 전엔 조용히. Profiler 재측정으로 한 글자 commit 이 1-2ms 까지 떨어지는지 확인.

흔한 실수와 안티패턴

  • useState 와 RHF 를 섞어 쓰면 또 그 useState 가 리렌더 원인이 됨 — 완전히 RHF 한 모델로 통일
  • Controller 를 모든 필드에 사용 — 그러면 RHF 의 핵심 이득이 사라짐. 정말 필요한 필드만
  • `register("a")` 의 `a` 를 동적 키로 만들 때 join 실수 — TypeScript 가 잡아주지만 인덱스 시그니처를 정확히 정의해야
  • 서버 검증을 생략하고 클라 Zod 만 신뢰 — DevTools 로 우회 가능, 동일 스키마를 서버에서도 반드시 적용
  • onChange 모드를 켜고 비동기 검증(중복 이메일) 을 매 입력마다 호출 — 디바운스 또는 onBlur 로 옮길 것

면접 질문

중급토스카카오배민

답변 방향 힌트

Controlled 모델에서 setState → 리렌더 사이클이 어떻게 폼 전체에 퍼지는지, 그리고 그것을 끊는 두 가지 방법.

반드시 언급할 키워드

  • Controlled 모델은 onChange 마다 setState → 폼 컴포넌트 리렌더 → 모든 자식 필드 리렌더
  • 필드 수가 많아질수록 한 입력의 commit 시간이 선형 증가
  • 접근 1: 모델 자체를 uncontrolled(ref) 로 — RHF 가 표준. 리렌더 0
  • 접근 2: Controlled 유지하되 필드 단위로 컴포넌트 분리 + memo + 자체 state
  • 근본 해결은 1번 — React.memo, useCallback 으로 우회는 한계가 큼

예상 꼬리 질문

  • React Hook Form 의 Controller 는 언제 써야 하고, 쓰면 어떤 비용이 생기나요?
  • useTransition 으로 input 을 감싸면 큰 폼이 빨라진다는 주장에 대해 어떻게 반박할 건가요?

자기 점검

스크롤 올리지 말고 답해보세요. Controlled 와 Uncontrolled 컴포넌트의 차이를 한 문장으로.

기대 키워드

valuestaterefDOMdefaultValue

자주 하는 오해

"controlled 가 항상 옳다" 고 외우는 경우가 많습니다. 작은 폼에서는 맞지만 큰 폼에서는 ref 기반 uncontrolled 가 성능 면에서 압도적이고, 두 모델은 trade-off 가 다릅니다.

React Hook Form 이 폼 전체 리렌더 없이 동작하는 두 가지 핵심 메커니즘은?

기대 키워드

registerrefDOMProxy구독formState

자주 하는 오해

"React Hook Form 은 useState 를 안 쓴다" 까지는 맞지만, 정확한 이유는 (1) 입력값을 ref(=DOM)에 저장하고 (2) formState 를 Proxy 로 추적해 구독한 부분만 리렌더하기 때문입니다.

Zod 스키마를 클라이언트만이 아니라 서버에서도 검증해야 하는 이유는?

기대 키워드

DevTools 우회직접 fetch보안단일 진실의 원천safeParse

자주 하는 오해

"클라에서 막으면 안전하다" 는 가장 위험한 오해. DevTools 로 onSubmit 우회나 직접 fetch 가 가능하므로 서버는 항상 같은 스키마로 다시 검증해야 합니다.

학습 자료