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);
사용 사례
- 로직 재사용성: 데이터 페칭, 인증, 상태 관리 등 공통 로직을 여러 컴포넌트에서 재사용할 때.
- 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>;
사용 사례
- 유연한 UI 설계: 드롭다운, 아코디언, 탭과 같은 컴포넌트.
- 구성 요소 관계 유지: 부모와 자식이 밀접한 상호작용이 필요할 때.
장점
- 직관적인 API: HTML 태그처럼 선언적으로 사용할 수 있음.
- 유연성: 부모 컴포넌트의 상태를 자식 컴포넌트 간에 쉽게 공유 가능.
단점
- 복잡성 증가: Context와 cloneElement를 적절히 사용해야 하므로 구현 난이도가 있음.
- 추적 어려움: 상태나 동작이 부모-자식 관계에 묶여있어 디버깅이 어려울 수 있음.
고차 컴포넌트 vs 컴파운드 컴포넌트
특징고차 컴포넌트컴파운드 컴포넌트
주요 목적 | 로직 재사용 | 구성 요소 간 관계 유지 및 협력 |
사용 방식 | 함수로 감싸서 로직 추가 | 부모-자식 형태의 선언적 사용 |
복잡성 | Wrapper Hell 발생 가능 | 부모-자식 관계에 종속되므로 디버깅이 어려울 수 있음 |
재사용성 | 높은 재사용성 | 특정 구성 요소에 종속적 |
사용 사례 | 인증, 로딩, 데이터 페칭 | 드롭다운, 아코디언, 탭 |
언제 어떤 패턴을 선택할까?
- 로직 재사용이 필요한 경우
공통된 비즈니스 로직을 여러 컴포넌트에서 재사용하고 싶다면 HOC를 사용하는 것이 적합합니다. 예를 들어, 인증 체크나 데이터 로딩 로직은 HOC로 처리하기 쉽습니다. - 구성 요소 간 긴밀한 관계가 필요한 경우
드롭다운, 아코디언처럼 부모와 자식 간의 상태 공유와 협력이 필요한 UI를 설계할 때는 컴파운드 컴포넌트를 사용하는 것이 더 자연스럽습니다. - 코드 가독성
프로젝트가 점점 커질수록 중첩된 HOC는 복잡도를 높일 수 있습니다. 따라서 적절한 패턴을 선택하여 가독성을 유지해야 합니다.
결론
고차 컴포넌트와 컴파운드 컴포넌트는 각각의 목적과 사용 사례가 명확합니다. HOC는 로직 재사용에 강력하며, 컴파운드 컴포넌트는 부모-자식 관계를 표현하는 선언적이고 직관적인 방식에 유리합니다. 프로젝트의 요구사항에 따라 적절한 패턴을 선택하는 것이 중요합니다.