프론트엔드에서 사용하기 좋은 Design Pattern - Compound Components Pattern

Kychann·2025년 4월 29일
post-thumbnail

🛠 Compound Components Pattern

개념

  • 여러 컴포넌트가 하나의 상태나 컨텍스트를 공유
  • 마치 부품처럼 조립해서 사용하게 만듦

하나의 큰 컴포넌트 안에 여러 작은 컴포넌트를 자식처럼 함께 묶어두고,

그 자식 컴포넌트들이 부모의 상태나 기능을 자연스럽게 사용할 수 있게 만든다.


왜 사용할까?

  • 유연한 API 제공
    - 사용하는 쪽이 구성 요소를 자유롭게 조합할 수 있음
  • 코드 가독성 향상
    - 명확하게 어떤 구조로 사용할지 눈에 보임
  • 상태 공유가 자연스러움
    - 부모가 제공하는 Context를 자식이 암묵적으로 사용 가능

예시 (Toggle Component)

➡️ 예를 들어, “Toggle” 컴포넌트를 만든다고 해보자.

// Toggle.js
import { createContext, useContext, useState } from "react";

// 1. Context 생성
const ToggleContext = createContext();

// 2. Toggle 컴포넌트 (부모)
function Toggle({ children }) {
  const [on, setOn] = useState(false);
  const toggle = () => setOn(prev => !prev);

  return (
    <ToggleContext.Provider value={{ on, toggle }}>
      {children}
    </ToggleContext.Provider>
  );
}

// 3. Toggle 하위 부품 (자식)
Toggle.Button = function ToggleButton({ children }) {
  const { toggle } = useContext(ToggleContext);
  return <button onClick={toggle}>{children}</button>;
};

Toggle.Message = function ToggleMessage({ children }) {
  const { on } = useContext(ToggleContext);
  return on ? <div>{children}</div> : null;
};

export default Toggle;

➡️ 사용하는 쪽에서는 이렇게 자유롭게 조립!

<Toggle>
  <Toggle.Button>Switch</Toggle.Button>
  <Toggle.Message>Toggle is ON!</Toggle.Message>
</Toggle>

구조 그림

[Toggle]  -- Context 제공
 ├── [Toggle.Button]  -- 버튼 기능
 └── [Toggle.Message] -- 메시지 표시

장점 요약

장점설명
높은 유연성사용자가 원하는 방식으로 조립 가능
강한 내부 일관성자식 컴포넌트들은 부모 Context를 자동 공유
깔끔한 API<Toggle.Button>, <Toggle.Message> 처럼 읽기 쉽고 직관적

주의할 점

  • Context 사용을 잊으면 에러
    - 하위 컴포넌트가 반드시 부모 컴포넌트 안에 있어야 함
  • Context 없을 때 에러 처리 추가 추천
    - useContext를 쓸 때, 값이 없으면 에러를 던지는 식으로 안전하게 작성 가능.
function useToggle() {
  const context = useContext(ToggleContext);
  if (!context) {
    throw new Error("Toggle compound components must be used inside a <Toggle>");
  }
  return context;
}
profile
컴포넌트는 재사용, 감성은 1회용

0개의 댓글