프론트엔드 기초집LESSON 10
폼과 Controlled Component
난이도초급
예상 시간35분
선수지식이전 강의
10강. 폼과 Controlled Component
1. 이번 강의에서 해결할 문제
입력 요소가 늘어나면 각 DOM 값과 React state가 어긋나기 쉽습니다. 검색 조건을 예측 가능하게 관리하고 폼 제출 시 페이지가 새로고침되지 않게 해야 합니다.
2. 학습 목표
- controlled input의 value와 onChange를 연결한다.
- submit 이벤트의 기본 동작을 제어한다.
- 여러 폼 값을 하나의 상태 객체로 갱신한다.
3. 핵심 개념
Controlled Component는 입력값의 원본을 React state에 두는 방식입니다. input의 value는 state에서 받고 onChange로 state를 갱신합니다. 따라서 버튼으로 초기화하거나 여러 조건을 한 번에 적용하기 쉽습니다.
객체 state를 바꿀 때는 기존 객체를 직접 수정하지 않고 펼침 문법으로 새 객체를 만듭니다.
4. 단계별 코드 예시
파일 경로: game-release-dashboard/src/components/FilterForm.tsx
import { useState, type FormEvent } from 'react';
type Filters = { query: string; platform: string };
type FilterFormProps = { onApply: (filters: Filters) => void };
export function FilterForm({ onApply }: FilterFormProps) {
const [draft, setDraft] = useState<Filters>({
query: '',
platform: 'all',
});
function handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
onApply(draft);
}
function resetFilters() {
const empty = { query: '', platform: 'all' };
setDraft(empty);
onApply(empty);
}
return (
<form onSubmit={handleSubmit}>
<label>
게임 제목
<input
value={draft.query}
onChange={(event) =>
setDraft({ ...draft, query: event.target.value })
}
/>
</label>
<label>
플랫폼
<select
value={draft.platform}
onChange={(event) =>
setDraft({ ...draft, platform: event.target.value })
}
>
<option value="all">전체</option>
<option value="PC">PC</option>
<option value="Console">Console</option>
</select>
</label>
<button type="submit">적용</button>
<button type="button" onClick={resetFilters}>초기화</button>
</form>
);
}
5. 코드가 동작하는 이유
브라우저의 submit은 기본적으로 페이지를 이동시키므로 preventDefault로 막습니다. 입력할 때마다 새 draft 객체가 만들어지고, 적용 버튼은 현재 초안을 부모 콜백에 전달합니다. 초기화 버튼은 submit이 아니므로 type을 명시합니다.
6. 자주 하는 실수와 해결법
- value만 지정하고 onChange 누락: 입력이 읽기 전용이 됩니다. 둘을 함께 연결합니다.
draft.query = ...로 직접 수정: 새 객체를 setter에 전달합니다.- 모든 버튼이 폼을 제출: 보조 버튼은
type="button"을 사용합니다. - label 없는 입력: 보이는 label 또는 명확한 aria-label을 제공합니다.
7. 직접 실습
최소 랭킹 점수를 입력하는 number input을 추가하세요. 빈 문자열은 허용하고 제출할 때 0~100 범위인지 검사해 오류 문구를 표시하세요.
8. 이해 점검 질문 3개
- controlled input의 데이터 원본은 어디인가요?
- 폼 submit에서 preventDefault가 필요한 이유는 무엇인가요?
- 객체 state를 직접 수정하면 왜 문제가 되나요?
9. 핵심 요약
제어 폼은 입력값을 state와 동기화합니다. 제출, 검증, 초기화를 React 흐름 안에서 일관되게 처리할 수 있습니다.
MINI QUIZ
0 / 2폼과 Controlled Component 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
LESSON STATUS
10강. 폼과 Controlled Component 미완료 상태학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.