리액트에서는 모든 컴포넌트가 props를 받을 수 있지만
children prop은 특별한 역할을 하는데
컴포넌트 태그 내부에 있는 내용을 동적으로 전달할 때 사용하고
레이아웃 컴포넌트, 재사용 가능한 UI 요소 등을 만들 때 매우 유용하다.
기본적으로는 props는 부모 -> 자식으로 데이터를 전달하는 역할을 한다고 했을 때,
children prop은 컴포넌트 태그 사이의 내용을 가져오는 역할을 한다.
즉 children을 사용하면 부모 컴포넌트에서 원하는 내용을 동적으로 넣을 수 있다.
children prop 기본 사용법
// Card.jsx
function Card({ children }) {
return (
<div className='card'>
{/* children을 통해 태그 내부의 내용을 랜더링 */}
{children}
</div>
)
}
export default Card
// App.jsx
import Card from "./Card"
function App() {
return (
<div>
<Card>
<h2>카드 컴포넌트 입니다.</h2>
<p>원하는 내용 입력 가능</p>
</Card>
<Card>
<button>버튼 기능 추가 가능</button>
</Card>
</div>
)
}
export default App
이렇게 children을 활용하여 컴포넌트 내부에 동적인 내용을 넣을 수 있으며
Card 컴포넌트를 어떤 용도로든 재사용이 가능하다. (ex: h2, p, button 등)

children - 간단한 사용 예제 (Layout, Modal...)
페이지 레이아웃을 만들 때 children을 사용하면 코드가 더 깔끔해지고 관리하기 편하다.
// Layouy.jsx
function Layout({ children }) {
return (
<div>
<header>헤더 부분</header>
<main>{children}</main> {/* 이 부분에 동적인 콘텐츠가 들어감 */}
<footer>푸터 부분</footer>
</div>
)
}
export default Layout
// App.jsx
import Card from "./Card"
import Layout from "./Layout"
function App() {
return (
<div>
<Layout>
<Card>
<h2>카드 컴포넌트 입니다.</h2>
<p>원하는 내용 입력 가능</p>
</Card>
<Card>
<button>버튼 기능 추가 가능</button>
</Card>
</Layout>
</div>
)
}
export default App
위와 같이 children 안에 원하는 페이지 내용을 넣어서
레이아웃을 모든 페이지에서 재사용 가능하다.
이 방법은 실제 프로젝트에서 헤더와 푸터가 고정된 레이아웃을 만들 때 자주 사용된다.

또한 팝업(모달) 창을 만들 때도 children을 활용하여 더 유연한 UI를 구성할 수 있다
(단 useState로 열고 닫는 기능까지 추가해야 하므로 다음 기회에..)
children - 스타일 적용
마찬가지로, 스타일링을 하여 색상이나 폰트 등 유연하게 변경할 수 있다.
// Color.jsx
function Color({ children, backgroundColor }) {
return (
<div style={{ backgroundColor, padding: "20px", borderRadius: "10px" }}>
{children} {/* 안에 어떤 내용이든 들어갈 수 있음 */}
</div>
);
}
export default Color;
// App.jsx
import Card from "./Card"
import Layout from "./Layout"
import Color from "./Color"
function App() {
return (
<div>
<Layout>
<Card>
<h2>카드 컴포넌트 입니다.</h2>
<p>원하는 내용 입력 가능</p>
</Card>
<Color backgroundColor="lightblue" >
<p>연한 파란색</p>
</Color>
<Color backgroundColor="lightpink" >
<p>연한 핑크색</p>
</Color>
<Card>
<button>버튼 기능 추가 가능</button>
</Card>
</Layout>
</div>
)
}
export default App

Color 컴포넌트를 사용할 때마다 다른 색상을 설정할 수 있다.
children - propTypes
children도 props의 일종이기 때문에
propTypes를 사용하여 유효성 검사를 추가해 주는 것이 좋다.
children을 사용할 경우에도 propTypes를 설정하지 않으면
다른 props와 마찬가지로 ESlint 경고가 발생한다.
// Card.jsx - propTypes 추가
import Proptypes from "prop-types"
function Card({ children }) {
return (
<div className='card'>
{/* children을 통해 태그 내부의 내용을 랜더링 */}
{children}
</div>
)
}
// children을 `node` 타입으로 지정 (React 요소, 문자열, 숫자 등 허용)
Card.propTypes = {
children: Proptypes.node.isRequired, // children이 필수 값임을 명시
};
export default Card
// Color.jsx - PropTypes 추가
import PropTypes from "prop-types"
function Color({ children, backgroundColor }) {
return (
<div style={{ backgroundColor, padding: "20px", borderRadius: "10px" }}>
{children} {/* 안에 어떤 내용이든 들어갈 수 있음 */}
</div>
);
}
Color.propTypes = {
children: PropTypes.node.isRequired,
backgroundColor: PropTypes.string // backgroundColor는 css 속성이므로 string
}
export default Color;
// Layouy.jsx - Proptypes 추가
import PropTypes from "prop-types"
function Layout({ children }) {
return (
<div>
<header>헤더 부분</header>
<main>{children}</main> {/* 이 부분에 동적인 콘텐츠가 들어감 */}
<footer>푸터 부분</footer>
</div>
)
}
Layout.propTypes = {
children: PropTypes.node.isRequired
}
export default Layout
여기서 코드를 보면 PropTypes.node에서 node라는 단어가 나오게되는데,
children은 여러가지 타입을 가질 수 있으며 node, element, string,number등의 타입이 존재한다.
어떤 타입을 지정해야 하는지 방법을 알아보자.
▶ children에 사용할 수 있는 propTypes 타입
리액트에서는 children의 타입을 일반적으로 node로 설정하는 것이 적합하다.
타입 | 설명 | 사용 예제 |
PropTypes.node | 모든 리액트 랜더링 가능한 요소 (문자열, 숫자, JSX 배열 등) |
<Card>텍스트</Card> <Card><h1>제목</h1></Card> |
PropTypes.element | 리액트 요소만 가능 (JSX 컴포넌트) | <Card><h1>제목</h1></Card> |
PropTypes.string | 문자열만 가능 | <Card>텍스트</Card> |
PropTypes.number | 숫자만 가능 | <Card>{123}</Card> |
즉 PropTypes.node를 사용하면 대부분의 경우를 포함할 수 있기 때문에 node를 주로 설정한다.
설명을 더해서, Proptyles.node와 PropTypes.element의 차이점은
node는 React에서 렌더링할 수있는 거의 모든 값을 포함하기 때문에 일반적으로 더 유용하며
element는 JSX 요소만 받을 때 사용하기 때문에 node보다 조금 덜 사용된다.
그리고 backgroundColor는 CSS 속성으로 사용되기 때문에 PropTypes.string을 사용했으며
node로는 사용할 수 없고 왜 string으로 사용하는지 알아보자
backgroundColor는 CSS에서 색상을 나타내는 문자열 값인데
여기서 중요한 점은 "문자열 값" 이다
backgroundColor: "red" // 문자열
backgroundColor: "#ff0000" // 문자열
backgroundColor: "rgb(255, 0, 0)" // 문자열
위 코드를 보면 전부 문자열로 색상을 지정하고 있다.
그러므로..
PropTypes.node 는 JSX요소 (div,h1)와 관련됨 -> 배경색과 무관함!
PropTypes.element 는 JSX요소 (React.createELement())와 관련됨 -> 역시나 배경색과 무관함
▶ children의 isRequired
children이 필수( isRequired )인지 여부는 컴포넌트 사용방식에 따라 다르다.
isRequired를 사용하면 컴포넌트를 사용할 때 children이 반드시 있어야 하므로
children을 빼먹으면 ESLint 경고가 뜰 것이다.
하지만 isRequired가 없으면 children이 없어도 정상적으로 동작할 것이다.
또한 defaultProps를 사용하면 children이 없을 때 기본값을 설정할 수 있다.
// children이 필수일 경우
Card.propTypes = {
children: PropTypes.node.isRequired,
};
// children이 선택 사항일 경우 (isRequired 없이 기본값 설정)
Card.propTypes = {
children: PropTypes.node,
};
Card.defaultProps = { // defaultProps를 사용하면 children이 없을 때 기본값을 설정
children: "기본 내용입니다.", // 기본값 설정
};
정리하면 다음과 같다.
- children은 리액트에서 태그 내부의 내용을 동적으로 전달하는 props이다.
- Card, Layout 등 재사용 가능한 컴포넌트를 만들 때 사용된다.
- children을 활용하면 컴포넌트의 유연성이 증가하고 재사용성이 높아진다.
- children도 prop의 일부이므로 propTypes로 유효성 검사를 해야한다.
- isRequired를 추가하면 children을 필수값으로 설정할 수 있다.
'React' 카테고리의 다른 글
React - React의 렌더링 방식 : State (0) | 2025.02.27 |
---|---|
React - State (0) | 2025.02.26 |
React - props (0) | 2025.02.20 |
React - 리액트 컴포넌트 (React Component) (0) | 2025.02.19 |
React - JSX에서 자바스크립트 사용하기 (0) | 2025.02.17 |