: 자식 컴포넌트들이 부모 컴포넌트 내부의 상태를 공유하면서 비즈니스 로직과 사용자 인터페이스와 관련된 부분을 구분하는 React 디자인 패턴
→ 하나의 복합적인 컴포넌트를 여러 개의 서브 컴포넌트로 분리하고, 사용자가 원하는 형태로 서브 컴포넌트들을 조립하여 구성하는 디자인 패턴
- 가장 쉬운 대표적인 예시 <select>, <option> 태그
<select>
<option value="react">React</option>
<option value="next">Next</option>
<option value="angular">Angular</option>
</select>
→ 부모 컴포넌트(select)가 상태를 관리하고, 자식 컴포넌트(option)들이 그 상태를 공유하면서 하나의 완성된 UI 구성
이처럼 부모와 자식 컴포넌트가 유기적으로 결합되어 동작하는 구조가 Compound Component Pattern의 핵심!
Compound Component Pattern은 보통 React의 Context API를 활용해 구현함
→ 부모 컴포넌트의 상태와 함수를 자식 컴포넌트에서 props 없이 바로 사용 가능
import { createContext, useContext, useState } from "react";
const CardContext = createContext();
export function Card({ children }) {
const [selected, setSelected] = useState(null);
return (
<CardContext.Provider value={{ selected, setSelected }}>
<div className="card">{children}</div>
</CardContext.Provider>
);
}
Card.Title = function CardTitle({ children }) {
return <h2>{children}</h2>;
};
Card.Body = function CardBody({ children }) {
return <div>{children}</div>;
};
Card.Item = function CardItem({ children }) {
const { selected, setSelected } = useContext(CardContext);
return (
<div
style={{
background: selected === children ? "skyblue" : "white",
cursor: "pointer",
}}
onClick={() => setSelected(children)}
>
{children}
</div>
);
};
<Card>
<Card.Title>Component compound pattern</Card.Title>
<Card.Body>
<Card.Item>부모와 자식으로 UI와 논리 분리</Card.Item>
<Card.Item>Props 대신 자식 컴포넌트로 전달</Card.Item>
<Card.Item>컴포넌트의 재사용성 향상</Card.Item>
</Card.Body>
</Card>
위처럼 작성하면 코드의 가독성이 높아지고, 컴포넌트의 구조를 직관적으로 이해할 수 있음.