컴포넌트는 단독으로 사용이 가능하지만, 다른 컴포넌트를 감싸는 wrapper
컴포넌트로도 사용이 가능하다
<Card className='expenses'>
<ExpenseItem title={props.items[0].title} />
<ExpenseItem title={props.items[1].title} />
<ExpenseItem title={props.items[2].title} />
<ExpenseItem title={props.items[3].title} />
</Card>
wrapper
컴포넌트로 사용할 경우, 해당 컴포넌트에 작성된 요소들은 children
이라는 props
로 하위 컴포넌트에 전달된다
wrapper
컴포넌트에서는 반드시 children
을 리턴해야 출력이 된다
// Card.js
function Card(props) {
const classes = 'card ' + props.className
return (
<div className={classes}>{props.children}</div>
)
}
Card
컴포넌트가 감싸는 컴포넌트는 classes
css가 적용된 div
로 감싸져있다
return문 내부의 div에는 두 개의 css가 적용된다
className={card + Card가 하위 컴포넌트에서 쓰일 때의 className
}
// ExpenseItem.js
function ExpenseItem(props) {
return (
<Card className='expense-item'>
<ExpenseDate date={props.date} />
<div className='expense-item__description'>
<h2>{props.title}</h2>
<div className='expense-item__price'>${props.amount}</div>
</div>
</Card>
)
}
Card 컴포넌트가 ExpenseItem
컴포넌트에서 쓰일 때 className은 expense-item
이다
그렇지만 Card
컴포넌트에서는 card
라는 className도 적용이 되었으므로, ExpenseItem
컴포넌트에는 두 개의 css가 적용된 것이다
// Card.css
.card {
border-radius: 12px;
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.25);
}
// ExpenseItem.js
.expense-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem;
margin: 1rem 0;
border-radius: 12px;
background-color: #4b4b4b;
}
👉 ExpenseItem
컴포넌트에서는 card와 expense-item의 스타일이 다 적용 됨