My Boundary As Much As I Experienced

고차 컴포넌트 vs 컴파운드 컴포넌트 본문

FrontEnd/React

고차 컴포넌트 vs 컴파운드 컴포넌트

Bumang 2024. 11. 14. 20:38

고차 컴포넌트와 컴파운드 컴포넌트 비교와 활용

React를 사용하다 보면 컴포넌트 구조를 설계하는 방법으로

고차 컴포넌트와 컴파운드 컴포넌트라는

두 가지 패턴을 만나게 됩니다. 이 글에서는 두 패턴의 개념, 사용 사례, 그리고 장단점을 비교해 보며,

각각을 언제 선택하면 좋은지 살펴보겠습니다.

 

 

고차 컴포넌트(Higher-Order Components)

개념

고차 컴포넌트(HOC)는 하나의 컴포넌트를 인자로 받아 새로운 컴포넌트를 반환하는 함수입니다.

React에서 로직 재사용성을 높이기 위해 사용되는 패턴입니다.

const withLoading = (WrappedComponent) => {
  return (props) => {
    if (props.isLoading) {
      return <div>Loading...</div>;
    }
    return <WrappedComponent {...props} />;
  };
};

const MyComponent = (props) => <div>{props.data}</div>;

const EnhancedComponent = withLoading(MyComponent);

 

사용 사례

  1. 로직 재사용성: 데이터 페칭, 인증, 상태 관리 등 공통 로직을 여러 컴포넌트에서 재사용할 때.
  2. React 라이브러리: Redux의 connect 함수나 Apollo의 graphql HOC와 같은 패턴.

장점

  • 로직 추상화: UI와 비즈니스 로직을 분리하여 유지보수성을 높임.
  • 코드 재사용: 반복적인 로직을 HOC로 감싸기만 하면 재사용 가능.

단점

  • Wrapper Hell: 여러 HOC를 중첩하면 가독성이 떨어질 수 있음.
  • Prop Drilling: HOC가 전달하는 props가 많아질 경우 관리가 복잡해질 수 있음.

 

 

컴파운드 컴포넌트(Compound Components)

개념

컴파운드 컴포넌트는 부모 컴포넌트와 자식 컴포넌트가 긴밀하게 협력하여 구성 요소를 조합할 수 있도록 설계된 패턴입니다. React의 Context를 활용하는 경우가 많습니다.

 

const Accordion = ({ children }) => {
  const [openIndex, setOpenIndex] = React.useState(null);

  return (
    <div>
      {React.Children.map(children, (child, index) =>
        React.cloneElement(child, {
          isOpen: openIndex === index,
          onToggle: () => setOpenIndex(openIndex === index ? null : index),
        })
      )}
    </div>
  );
};

Accordion.Item = ({ isOpen, onToggle, children }) => (
  <div onClick={onToggle}>
    {isOpen ? <div>{children}</div> : <div>Click to Open</div>}
  </div>
);

// 사용 예시
<Accordion>
  <Accordion.Item>Item 1</Accordion.Item>
  <Accordion.Item>Item 2</Accordion.Item>
</Accordion>;

 

사용 사례

  1. 유연한 UI 설계: 드롭다운, 아코디언, 탭과 같은 컴포넌트.
  2. 구성 요소 관계 유지: 부모와 자식이 밀접한 상호작용이 필요할 때.

장점

  • 직관적인 API: HTML 태그처럼 선언적으로 사용할 수 있음.
  • 유연성: 부모 컴포넌트의 상태를 자식 컴포넌트 간에 쉽게 공유 가능.

단점

  • 복잡성 증가: Context와 cloneElement를 적절히 사용해야 하므로 구현 난이도가 있음.
  • 추적 어려움: 상태나 동작이 부모-자식 관계에 묶여있어 디버깅이 어려울 수 있음.

 

 

고차 컴포넌트 vs 컴파운드 컴포넌트

특징고차 컴포넌트컴파운드 컴포넌트

주요 목적 로직 재사용 구성 요소 간 관계 유지 및 협력
사용 방식 함수로 감싸서 로직 추가 부모-자식 형태의 선언적 사용
복잡성 Wrapper Hell 발생 가능 부모-자식 관계에 종속되므로 디버깅이 어려울 수 있음
재사용성 높은 재사용성 특정 구성 요소에 종속적
사용 사례 인증, 로딩, 데이터 페칭 드롭다운, 아코디언, 탭

 

 

언제 어떤 패턴을 선택할까?

  1. 로직 재사용이 필요한 경우
    공통된 비즈니스 로직을 여러 컴포넌트에서 재사용하고 싶다면 HOC를 사용하는 것이 적합합니다. 예를 들어, 인증 체크나 데이터 로딩 로직은 HOC로 처리하기 쉽습니다.
  2. 구성 요소 간 긴밀한 관계가 필요한 경우
    드롭다운, 아코디언처럼 부모와 자식 간의 상태 공유와 협력이 필요한 UI를 설계할 때는 컴파운드 컴포넌트를 사용하는 것이 더 자연스럽습니다.
  3. 코드 가독성
    프로젝트가 점점 커질수록 중첩된 HOC는 복잡도를 높일 수 있습니다. 따라서 적절한 패턴을 선택하여 가독성을 유지해야 합니다.

 

 

결론

고차 컴포넌트와 컴파운드 컴포넌트는 각각의 목적과 사용 사례가 명확합니다. HOC는 로직 재사용에 강력하며, 컴파운드 컴포넌트는 부모-자식 관계를 표현하는 선언적이고 직관적인 방식에 유리합니다. 프로젝트의 요구사항에 따라 적절한 패턴을 선택하는 것이 중요합니다.