---
type: knowledge
domain: frontend
status: active
last-reviewed: 2026-07-27
---

# 컴포넌트 설계 실전

> 한 줄 정의
> 컴포넌트는 재사용 단위이기 전에 **변경 격리 단위**다 — 상태 4분류·렌더링 전략은 [[프론트엔드 원리]], 경계 결정·납품 연결은 [[03_프론트엔드 설계]] — 여기는 쪼개고 계약하는 실전 기준이다.

## 분리 기준 — 재사용보다 변경 이유

| 신호 | 판단 |
|------|------|
| 같은 UI가 2곳 이상에서 반복 | 추출 후보. **2회 미만이면 추출하지 않는다** — 미래 재사용 예측은 대부분 틀린다 |
| 한 컴포넌트가 서로 다른 이유로 자꾸 수정됨 | 재사용과 무관하게 분리 — 변경 이유가 곧 경계다 |
| 파일이 길다는 이유만 | 분리 사유 아님. 길어도 한 가지 일을 하면 그대로 둔다 |
| 조건 분기(if variant)가 렌더 트리를 갈라놓음 | 변형별 컴포넌트로 분리 — 분기 누적은 "모든 걸 하는 컴포넌트"의 시작 |

- 성급한 추상화의 복구 비용 > 중복의 복구 비용. **중복은 두 번까지 허용하고, 세 번째에 패턴이 보이면 추출**한다.

## props 계약 — 컴포넌트의 공개 API

- props는 인터페이스 계약이다. 내부 구현 사정(서버 응답 구조 등)을 그대로 props로 노출하면 API 변경이 화면 전체로 번진다 — 컴포넌트가 필요한 모양으로 좁혀 받는다.
- **불리언 폭발 금지**: `isSmall` `isLarge` `isOutlined` `isDanger`가 쌓이면 조합 수는 2^n이고 대부분은 무의미·모순 조합이다. `variant="danger"` `size="sm"` 같은 열거형으로.
- **합성 우선**: 헤더·푸터·액션 영역을 props 옵션 10개로 받지 말고 children·슬롯으로 열어 둔다. "옵션 추가 요청이 반복되는 컴포넌트"는 합성으로 전환하라는 신호다.
- 필수 props는 적을수록 좋다 — 기본값 없는 필수 props 8개짜리 컴포넌트는 사용처마다 복붙을 낳는다.

## 컨테이너/프레젠테이션의 현대적 형태 — 데이터 훅 분리

컨테이너 컴포넌트 계층을 별도로 두는 고전 패턴은 낡았지만, **"데이터 획득과 표시의 분리"라는 본질은 유효**하다. 현대적 형태는:

- 데이터 패칭·가공은 **커스텀 훅**(또는 프레임워크의 로더)으로 — 컴포넌트는 훅이 준 값을 그리기만.
- 표시 컴포넌트는 props만으로 렌더 가능하게 — 그래야 테스트가 API 없이 돌고([[프론트엔드 테스트 실전]]), 스토리·문서화가 가능하다.
- 서버 상태를 props 드릴링으로 깊이 나르지 않는다 — 필요한 곳에서 캐시 훅으로 직접 조회 ([[프론트엔드 원리]] 서버 상태=캐시).

## 디자인 토큰·스타일 계층

| 계층 | 내용 | 규율 |
|------|------|------|
| 토큰 | 색·간격·타이포·radius 원자값 | 하드코딩 금지 — `#3B82F6` 대신 `--color-primary`. 발주사 브랜드 변경이 토큰 한 곳 수정으로 끝나게 |
| 기본 컴포넌트 | 버튼·입력·모달 등 토큰만 소비 | 도메인 지식 금지 — "주문 취소 버튼"이 아니라 "danger 버튼" |
| 도메인 컴포넌트 | 화면 요소 (주문 카드 등) | 기본 컴포넌트 조합 + 도메인 로직 |

- 시각 규칙 자체는 [[UI 시각 체계]]·[[디자인 시스템]] 소관 — 여기서는 "토큰을 우회한 스타일 하드코딩이 유지보수 폭탄"이라는 규율만.
- 폐쇄망 납품이면 외부 CDN 폰트·아이콘 로드는 전부 막힌다 — 번들에 포함 ([[03_프론트엔드 설계]]).

## 폴더 구조 — 판단 기준

- 기준은 하나: **함께 바뀌는 것을 함께 둔다.** 기능(주문·정산) 단위 폴더가 기본값, `components/` `hooks/` `utils/` 같은 종류별 전역 통은 공용층에만.
- 공용 승격은 실제 2번째 사용처가 생겼을 때 — "언젠가 쓸 것 같아서" 공용 폴더에 넣는 것이 죽은 코드의 출생지다.
- 외주 인수인계 관점: 폴더 구조 개요는 인수인계서 납품 항목이다 — 유지보수팀이 "이 화면 고치려면 어디를 여나"에 답할 수 있어야 검수를 통과한다.

## 안티패턴

- 만능 공용 컴포넌트 — props 20개짜리 `<CommonTable>`은 모든 화면의 수정이 서로를 깨뜨리는 단일 장애점이다.
- 서버 응답 객체를 그대로 최하위 컴포넌트까지 전달 — API 필드명 변경 하나가 전 화면 수정이 된다.
- 스타일 override 지옥 — 기본 컴포넌트를 사용처마다 `!important`로 덮으면 토큰 계층이 죽은 것이다. 변형이 필요하면 variant를 추가한다.

## 관련 문서

- [[프론트엔드 원리]] — 상태 4분류·데이터 패칭
- [[03_프론트엔드 설계]] — 컴포넌트 경계 결정·납품 산출물
- [[프론트엔드 테스트 실전]] — props 렌더 가능성=테스트 가능성
- [[디자인 시스템]] · [[UI 시각 체계]] — 토큰·시각 규칙 정본
- [[00_프론트엔드 허브]]
