children과 합성 — 컴포넌트 안에 컴포넌트를 넣습니다
Article
Props로 데이터를 전달하는 방법은 배웠습니다. 그런데 컴포넌트에 텍스트나 숫자가 아니라, 다른 컴포넌트 자체를 넣고 싶을 때는 어떻게 할까요?
children이란
HTML에서 태그 안에 내용을 넣는 건 익숙할 겁니다.
<div>
<p>안녕하세요</p>
</div>
React 컴포넌트도 똑같이 할 수 있습니다. 컴포넌트 태그 사이에 넣은 내용이 바로 children입니다.
<Card>
<p>이 내용이 children입니다</p>
</Card>
Card 컴포넌트 입장에서는 <p>이 내용이 children입니다</p> 부분이 children으로 전달됩니다.
function Card({ children }) {
return (
<div className="card">
{children}
</div>
);
}
이렇게 하면 Card 컴포넌트는 어떤 내용이든 감싸는 껍데기 역할을 합니다. 안에 뭘 넣든 자유입니다.
퍼블리셔에게 익숙한 개념
퍼블리싱을 해봤다면 레이아웃 include 패턴을 써본 적이 있을 겁니다. header와 footer는 고정이고, 가운데 콘텐츠 영역만 페이지마다 바뀌는 구조입니다.
children이 바로 그 콘텐츠 영역을 비워두는 슬롯과 같은 개념입니다. 껍데기는 고정하고, 안에 들어갈 내용만 바꿔 끼우는 겁니다.
합성으로 유연한 레이아웃 만들기
이 패턴을 **합성(Composition)**이라고 부릅니다. 컴포넌트를 조합해서 더 큰 구조를 만드는 방식입니다.
간단한 Card 컴포넌트를 예로 들어보겠습니다.
function Card({ children }) {
return (
<div className="border rounded-lg p-4 shadow-sm">
{children}
</div>
);
}
이 Card는 어디서든 재사용할 수 있습니다.
// 프로필 카드
<Card>
<h2>민수</h2>
<p>웹퍼블리셔</p>
</Card>
// 상품 카드
<Card>
<img src="/product.jpg" alt="상품" />
<p>29,000원</p>
</Card>
같은 Card 컴포넌트인데 안에 넣는 내용에 따라 전혀 다른 용도로 쓰이고 있습니다.
Layout 컴포넌트
실무에서 가장 많이 쓰이는 합성 패턴이 Layout 컴포넌트입니다.
function Layout({ children }) {
return (
<div>
<header>헤더 영역</header>
<main>{children}</main>
<footer>푸터 영역</footer>
</div>
);
}
사용할 때는 이렇게 씁니다.
<Layout>
<h1>홈페이지</h1>
<p>환영합니다</p>
</Layout>
header와 footer는 항상 고정이고, {children} 자리에 페이지별 콘텐츠가 들어갑니다. 퍼블리싱에서 하던 include 패턴과 원리가 같습니다. 표현 방식만 다를 뿐입니다.
정리
- children은 컴포넌트 태그 사이에 넣는 내용입니다.
- 컴포넌트를 껍데기로 만들고, 안에 뭘 넣을지는 사용하는 쪽에서 결정합니다.
- 이 방식을 **합성(Composition)**이라고 합니다.
- Layout, Card 같은 재사용 가능한 구조를 만들 때 핵심이 되는 패턴입니다.
children을 이해하면 컴포넌트 설계의 유연성이 크게 올라갑니다. 다음 글에서는 화면이 바뀌는 핵심 원리인 **상태(State)**를 알아보겠습니다.