React는 강력한 합성 모델을 가지고 있으며, 상속 대신 합성을 사용하여 Component 간에 코드를 재사용하는 것이 좋습니다.
이번 문서에서는 React를 처음 접한 개발자들이 종종 상속으로 인해 부딪히는 몇 가지 문제들과 합성을 통해 이러한 문제를 해결하는 방법을 살펴볼 것입니다.
어떤 Component 들은 어떤 자식 Element가 들어올 지 미리 예상할 수 없는 경우가 있습니다.
범용 적인 ‘박스’ 역할을 하는 Sidebar 혹은 Dialog와 같은 Component에서 특히 자주 볼 수 있습니다.
이러한 Component에서는 특수한 children prop을 사용하여 자식 Element를 출력에 그대로 전달하는 것이 좋습니다.
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
이러한 방식으로 다른 Component에서 JSX를 중첩하여 임의의 자식을 전달할 수 있습니다.
<FancyBorder> JSX 태그 안에 있는 것들이 FancyBorder Component의 children prop으로 전달됩니다. FancyBorder 는 {props.children}을 <div> 안에 렌더링하므로 전달된 Element들이 최종 출력됩니다.
흔하지 않지만 종종 Component에 여러 개의 “구멍”이 필요한 수도 있습니다. 이런 경우에는 children 대신 자신만의 고유한 방식을 적용할 수도 있습니다.
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
}
function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}
<Contacts /> 와 <Chat /> 같은 React Element는 단지 객체이기 때문에 다른 데이터처럼 prop으로 전달할 수 있습니다.
이러한 접근은 다른 라이브러리의 “슬롯(slots)”과 비슷해보이지만 React에서 prop으로 전달할 수 있는 것에는 제한이 없습니다.
때로는 어떤 Component의 “특수한 경우”인 Component를 고려해야 하는 경우가 있습니다.
예를 들어, WelcomeDialog 는 Dialog의 특수한 경우라고 할 수 있습니다.
React에서는 이 역시 합성을 통해 해결할 수 있습니다.
더 “구체적인” Component가 “일반적인” Component를 렌더링하고 props를 통해 내용을 구성합니다.