학습 목표: 컴포넌트를 박스처럼 만들고, 그 속에 내용을 자유롭게 담는 법을 배움
(1) children 받아쓰기
children은 특별한 이름의 Props임(고정임)
function Button({ children }) {
return <button>{children}</button>;
}
// 사용
<Button>저장하기</Button>
<Button>삭제하기</Button>
<Button>특별 버튼</Button>
(2) Props vs children - 언제 뭘 쓸까?
📛 Props: 정해진 데이터 전달
<ProductCard
name="사과"
price={1000}
imageUrl="apple.jpg"
/>
- 각 props가 역할이 정해져 있음(name, price, imageUrl)
- 주로 값(문자열, 숫자, 불린) 전달
- 컴포넌트마다 미리 정의된 슬롯에 꽂아넣는 느낌
📦 children: 자유로운 내용물 전달
<Card>
<h2>무엇이든</h2>
<p>넣어도 되는</p>
<img src="... />
<Button>자유 공간</Button>
</Card>
- 정해진 구조가 없음
- 텍스트, JSX, 다른 컴포넌트 뭐든 OK
- 컴포넌트를 범용 컨테이너로 만들 때 유용
🎯 판단 기준
| 상황 | 추천 |
| 값만 넘기면 됨(이름, 가격) | Props |
| 여러 요소 / 복잡한 JSX | children |
| 버튼 텍스트, 제목 같은 단순 텍스트 | children 권장 |
| 필수 데이터(사용자 정보 등) | Props |
(3) 실전 예제
예제 1: Card 컴포넌트 (가장 전형적)
function Card({ children }) {
return (
<div className="card">
{children}
</div>
);
}
다양하게 활용 가능
{/* 간단한 텍스트 */}
<Card>안녕하세요</Card>
{/* HTML 요소 */}
<Card>
<h2>제목</h2>
<p>내용</p>
</Card>
{/* 다른 컴포넌트 */}
<Card>
<UserProfile user={user} />
</Card>
예제 2: Button 컴포넌트
function Button({ children, onClick, variant = 'primary' }) {
return (
<button
className={`btn btn-${variant}`}
onClick={onClick}
>
{children}
</button>
);
}
사용
<Button onClick={handleSava}>저장</Button>
<Button variant="danger">삭제</Button>
{/* 이모지 + 텍스트 조합도 가능 */}
<Button>
이메일 보내기
</Button>
예제 3: Modal 컴포넌트
function Modal({ children, isOpen, onClose }) {
if (!isOpen) return null; // 열림 상태가 아니면 아무것도 안 보여줌
return (
<div className="modal-backdrop">
<div className="modal">
<button className="close" onClick={onClose}>x</button>
{children}
</div>
</div>
);
}
사용
<Modal isOpen={showModal} onClose={() => setShowModal(false)}>
<h2>알림</h2>
<p>정말 삭제하시겠습니까?</p>
<button onClick={handleDelete}>확인</button>
</Modal>
(4) children + 다른 props 조합
children과 다른 props는 자유롭게 섞어 쓸 수 있음
function Panel({ title, children, footer }) {
return (
<div className="panel">
<div className="panel-header">
<h3>{title}</h3>
</div>
<div className="panel-body">
{children} {/* 메인 컨텐츠 */}
</div>
{footer && (
<div className="panel-footer">
{footer}
</div>
)}
</div>
);
}
사용
<Panel
title="사용자 정보" {/* Props로 정해진 값 */}
footer={<button>저장</button>} {/* Props로 JSX도 전달 가능! */}
>
<input type="text" placeholder="이름" /> {/* children */}
<input type="email" placeholder="이메일" />
</Panel>
(5) 자주 하는 안티패턴
❌ 안티패턴 1: 단순 텍스트에 text props 남용
// ❌ 어색함 - React답지 않음
function Button({ text, onClick }) {
return <button onClick={onClick}>{text}</button>;
}
<Button text="저장" onClick={handleSave} />
// ✅ HTML처럼 자연스럽게
function Button({ children, onClick }) {
return <button onClick={onClick}>{children}</button>;
}
<Button onClick={handleSave}>저장</Button>
원칙: 텍스트나 JSX는 children으로!
❌ 안티패턴 2: 구조화된 데이터를 children으로
// ❌ 이런 건 Props로!
<UserCard>
홍길동
25
개발자
</UserCard>
// ✅ 정해진 구조는 Props
<UserCard name="홍길동" age={25} job="개발자" />
문제점: children은 자유로운 내용에 써야 함. 정해진 필드가 있다면 Props가 맞음
❌ 안티패턴 3: children이 빈 경우를 안 챙기
// ❌ children이 없으면 빈 카드가 튀어나옴
function Card({ children }) {
return <div className="card">{children}</div>;
}
<Card /> {/* 빈 카드 렌더링... */}
// ✅ 기본값 또는 안전 처리
function Card({ children = '내용 없음' }) {
return <div className="card">{children}</div>;
}'DEV > React' 카테고리의 다른 글
| [React 개발 기초] 8. 참조형 State (0) | 2026.08.10 |
|---|---|
| [React 개발 기초] 7. State (1) | 2026.08.10 |
| [React 개발 기초] 5. Props (0) | 2026.08.10 |
| [React 개발 기초] 4. 컴포넌트(Component) (0) | 2026.08.05 |
| [React 개발 기초] 3. JSX에서 JavaScript 사용하기 (0) | 2026.06.24 |