
하나의 큰 컴포넌트 안에 여러 작은 컴포넌트를 자식처럼 함께 묶어두고,
그 자식 컴포넌트들이 부모의 상태나 기능을 자연스럽게 사용할 수 있게 만든다.
➡️ 예를 들어, “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> 처럼 읽기 쉽고 직관적 |
function useToggle() {
const context = useContext(ToggleContext);
if (!context) {
throw new Error("Toggle compound components must be used inside a <Toggle>");
}
return context;
}