
컴파운드 컴포넌트 + Headless UI 톺아보기
Ant Design을 사용하면서 문득 이런 생각이 들었다.
“이 구조… 혹시 컴파운드 컴포넌트 패턴인가?”
꼬꼬무로 컴파운드 컴포넌트에 대해 알다보니 자연스럽게 Headless UI까지 연결지어 공부하게 됐다.
📍기존 컴포넌트의 방식
기존 리액트 컴포넌트는 props로 상태나 기능을 제어한다.
<Toggle on={true} onToggle={() => {}} />
- 버튼, 상태 표시 등 모든 역할이 하나 컴포넌트에 몰림
- props로만 제어 → 내부 로직을 모르고는 커스터마이징 어려움
→ 해결책: 컴포넌트를 조합하자!!!
📍컴파운드 컴포넌트란?
- 여러 개의 컴포넌트를 조합해 하나의 큰 컴포넌트를 만드는 패턴
- Context로 부모 상태를 자식들과 공유
- 자식 컴포넌트는 각자 역할에 집중
- 유연한 구조 + 재사용성 + 선언적 UI 구성 가능
기존에는 상태를 props로 넘기며 설계했지만, 컴파운드 컴포넌트는 Context로 내부 상태를 자식들이 공유하면서 더 유연하고 선언적인 UI 구성이 가능하게 만들어준다!
✨예시: Toggle 컴포넌트
<Toggle>
<Toggle.Button />
<Toggle.On>켜짐</Toggle.On>
<Toggle.Off>꺼짐</Toggle.Off>
</Toggle>
- props 없이 구성 가능
- 사용자에게 직관적인 UI 구조 제공
✨구현 원리
컴포넌트 내부에서 Context로 공유
const ToggleContext = createContext();
function Toggle({ children }) {
const [on, setOn] = useState(false);
return (
<ToggleContext.Provider value={{ on, setOn }}>
{children}
</ToggleContext.Provider>
);
}
- 부모 컴포넌트가 Context Provider로 상태 공유
- 자식 컴포넌트가
useContext로 상태 사용 - 각 자식 컴포넌트는 자신 역할만 수행 (On, Off, Button 등)
🤔 그럼 Ant Design은 컴파운드 패턴인가?
Ant Design은 ‘엄밀한 의미’의 컴파운드 컴포넌트 패턴 라이브러리는 아니다.
- 일부 컴포넌트(
Tabs,Menu,Select등)는 컴파운드 컴포넌트 패턴과 유사한 구조를 사용하지만, - Ant Design 전체가 컴파운드 패턴 기반으로 설계된 라이브러리는 아니고,
- 내부 상태 제어를 props 위주로 하고, 스타일과 동작이 강하게 결합된 완성형 UI 라이브러리다.
(공식문서엔 없지만 개발자 블로그에서 Ant Design의 구조에 대한 의견을 확인할 수 있었음)
https://nickb.dev/blog/decapitation-a-migration-from-antd-to-headless-story/
Headless UI란?
개발자: “디자인은 내가 정할게, 동작만 줘!”
- 스타일은 전혀 제공하지 않고, 동작과 상태 관리만 제공
- 사용자는 원하는 마크업과 스타일을 자유롭게 구성 가능
- 컴포넌트의 동작 로직만 분리해서 제공 (예: 열기/닫기, 포커스 관리, 키보드 접근성 등)
왜 Headless UI가 필요할까?
- 완성형 UI는 커스터마이징이 어렵고, 스타일 충돌이 생기기 쉬움
- Headless UI는 동작 로직만 제공 → 디자인 자유도 ↑
완성형 UI 라이브러리는 편리하지만, 스타일 커스터마이징이 어렵고 스타일 충돌 문제도 종종 생긴다.
컴파운드 컴포넌트와 Headless UI는 이런 문제를 해결하면서, 개발자에게 더 많은 자유도와 선언적인 UI 구성을 가능하게 해준다.
다음 글에서 내가 직접 구현한 예제를 기준으로, 컴파운드 컴포넌트와 Headless UI 스타일의 차이를 비교해봤다.
[🔥React 뽀개기] - UI 컴포넌트 라이브러리 비교(feat. Ant Design, HeadlessUI)
UI 컴포넌트 라이브러리 비교(feat. Ant Design, HeadlessUI)
UI 컴포넌트 라이브러리 비교[🔥React 뽀개기] - 컴파운드 컴포넌트 + Headless UI 톺아보기 컴파운드 컴포넌트 + Headless UI 톺아보기컴파운드 컴포넌트 + Headless UI 톺아보기Ant Design을 사용하면서 문득
bori-note.tistory.com
참고)
'✨FRONTEND > 📍React' 카테고리의 다른 글
| React에서 map 쓰는 패턴 정리 (0) | 2025.12.02 |
|---|---|
| UI 컴포넌트 라이브러리 비교(feat. Ant Design, HeadlessUI) (2) | 2025.06.01 |
| React 태그 입력 기능 구현하기 (0) | 2025.03.23 |
| Expo 알림(Notification) 구현하기 (2) | 2025.02.25 |
| Expo 앱 배포하기(웹 링크 + Expo QR 코드) (2) | 2025.02.15 |
