Contain: 담다, 포함하다.
하위 컴포넌트를 포함하는 형태의 합성 방법
Sidebar나 Dialog 같은 Box형태의 컴포넌트의 자신의 하위 컴포넌트를 미리 알 수 없음
→ Containment 방법을 사용
리액트 컴포넌트의 props에 기본적으로 들어있는 children 이라는 prop을 사용하여 조합
function FancyBorder(props){
return (
<div className = {'FancyBorder FancyBorder-' + props.color}>
{props.children}
// props.children을 사용하면 해당 컴포넌트의 하위 컴포넌트가 모두 children으로 들어옴
// children prop은 리액트에서 기본적으로 제공해줌.
</div>
);
}FancyBorder 컴포넌트를 사용하는 예제
Function WelcomeDialog(props){
return (
<FancyBorder color = "blue">
// FancyBorder 컴포넌트 안에 있는 모든 JSX 태그는
// children(props.children)으로 전달됨
<h1 className = "Dialog-title">
어서오세요
</h1>
<p className = "Dialog-message">
우리 사이트에 방문하신 것을 환영합니다!
</p>
</FancyBorder>
);
}
여러 개의 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(props) {
return(
<SplitPane left = {<Contacts />} right = {<Chat />}/>
);
}WelcomeDialog(구체적, 세부적)는 Dialog(범용적)의 특별한 케이스이다.
범용적인 개념을 구별이 되게 구체화 하는 것
객체지향 언어에서는 상속(inheritance)을 사용하여 Specialization을 구현하지만,
리액트에서는 합성(Composition)을 사용하여 Specialization을 구현한다.
// 범용적인 컴포넌트
function Dialog(props) {
return (
<FancyBorder color = "blue">
<h1 className = "Dialog-title">
{props.title}
</h1>
<p className = "Dialog-message">
{props.message}
</p>
</FancyBorder>
);
}
// 범용 컴포넌트를 사용하는 WelcomeDialog 컴포넌트
function WelcomeDialog(props) {
return (
<Dialog
title = "어서 오세요"
message = "우리 사이트에 방문하신 것을 환영합니다!"
/>
);
}
Composition과 대비되는 개념
객체 지향에서의 상속 : 부모 클래스를 상속받아 새로운 자식 클래스를 만드는 것. 자식 클래스는 부모 클래스가 가진 변수나 함수 등의 속성을 모두 갖음
리액트에서의 상속 : 다른 컴포넌트로부터 상속을 받아서 새로운 컴포넌트를 만드는 것
리액트를 개발한 Meta에서 상속을 권하지 않음.
→ 상속보다는 Composition(합성)을 사용하는 것이 더 좋은 방법
인용 자료 출처
처음 만난 리액트