본문 바로가기
✨FRONTEND/📍React

컴파운드 컴포넌트 + Headless UI 톺아보기

by 짱돌보리 2025. 6. 1.
728x90

컴파운드 컴포넌트 + 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

 

 

참고)