여러 개의 컴포넌트를 합쳐서 새로운 컴포넌트를 만드는 것
리액트를 개발하면서, 컴포넌트를 어떻게 합치는지에 따라 코드 가독성, 렌더링 성능, 유지보수 난이도 등이 변한다.
Container 같은 느낌으로, 하위 컴포넌트를 포함하는 형태의 합성 방법이다. 예를 들면, Sidebar, Dialog 같은 Box 형태의 컴포넌트는 자신의 하위 컴포넌트를 미리 알 수 없다. 이런 경우에 Containment를 활용해 Composition을 구현한다.
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
// 해당 prop는 리액트에서 기본적으로 제공하는 것이다.
{props.children}
</div>
);
}
function WelcomDialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
어서오세요
</h1>
<p className="Dialog-message">
우리 사이트에 방문하신 것을 환영합니다!
</p>
</FancyBorder>
);
}
props에 따로 정의해서 사용하면 된다.
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
}
// 카카오톡 같은 채팅앱 생각하면 됨
function App(props) {
return (
<SplitPane
left={ <Contacts /> } // 친구 목록
right={ <Chat /> } // 채팅
/>
);
}
범용적인 컴포넌트를 구체화하여 세부적인 컴포넌트로 따로 구분하는 것
Ex) WelcomeDialog는 Dialog의 일종이다.
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
</FancyBorder>
);
}
function WelcomeDialog(props) {
return (
<Dialog
title="어서 오세요"
message="우리 사이트에 방문하신 것을 환영합니다!"
/>
);
}
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
// Containement
{props.children}
</FancyBorder>
);
}
// Specialization
function SignUpDialog(props) {
const [nickname, setNickname] = useState('');
const handleChange = (event) => {
setNickname(event.target.value);
};
const handleSignUp = () => {
alert(`어서 오세요, ${nickname}님!`);
};
return (
<Dialog
title="화성 탐사 프로그램"
message="닉네임을 입력해주세요.">
<input
value={nickname}
onChange={handleChange} />
<button onClick={handleSignUp}>
가입하기
</button>
</Dialog>
);
}
자식 컴포넌트가 부모 컴포넌트의 속성을 그대로 물려받아 사용하는 것
Meta에서 연구한 결과, 그리 좋은 사용처를 찾지 못했다. 그래서 위의 Composition으로 충분한 듯