혹시나 잘못된 개념 전달이 있다면 댓글 부탁드립니다. 저의 성장의 도움이 됩니다.
합성이란 작게 쪼갠 컴포넌트들을 모아서 더 큰 컴포넌트를 생성하는 방식을 의미한다.
-> 재사용성을 위한 방식
컴포넌트의 열린 태그와 닫힌 태그 사이에 하위 컴포넌트를 포함하는 형태로 합성하는 방식을 의미한다.
<Card>
{/* 전달되는 위치 */} //<------- children 활용
</Card>
컴포넌트에 key를 지정하여 props를 내려주는 형태로 합성하는 방식을 의미한다.
<Card title={/* 타이틀 전달값 */} message={/* 메세지 전달값 */} ></Card>
// Card.js
import './Card.css'; //<-------------------------------- 배경색, 모서리 곡선 등 공통적인 CSS
const Card = (props) => {
return (
<div className={'card ' + props.className}> //<----- Specialization 방식
{props.children} //<------------------------------ Containment 방식
</div>);
};
export default Card;
// ExpenseItems.js
import './ExpenseItems.css';
import ExpenseDate from './ExpenseDate';
import Card from './Card';
const ExpenseItems = ({ title, amount, date }) => {
return (
<Card className="expense-item"> //<----------------- 클래스명은 Specialization 방식으로 적용
<ExpenseDate date={date} /> //<------------------- 여기부터 2번째</div>까지 children으로 전달되는 값
<div className="expense-item__description">
<h2>{title}</h2>
<div className="expense-item__price">{amount}</div>
</div>
</Card>
);
};
export default ExpenseItems;
위의 예제는 styled-componenets 없이 CSS를 재사용하기 위해 containment 방식을 사용했다.
ExpenseItems.js의 JSX <div className="expense-item">
대신 <Card>
컴포넌트로 감싸서 CSS를 적용시켰다. <div>
에는 className으로 원래 적용되어있던 CSS가 있었기 때문에, 합성 후에도 className 속성을 유지하려면 specialization 방식을 병행하면 된다.
CSS 재사용이 아니더라도 컴포넌트를 A,B,C 형태로 재사용할 때, B에서는 하위 요소가 더 추가되야하는 경우 containment 방식을 활용하면 될 것 같다.