์ฃผ์˜ํ•˜์„ธ์š”!

Children์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์ด์ง€ ์•Š๊ณ  ์ทจ์•ฝํ•œ ์ฝ”๋“œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์•ˆ์„ ์‚ดํŽด๋ณด์„ธ์š”.

Children์„ ์‚ฌ์šฉํ•ด์„œ children prop๋กœ ๋ฐ›์€ JSX๋ฅผ ์กฐ์ž‘ํ•˜๊ณ  ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const mappedChildren = Children.map(children, child =>
<div className="Row">
{child}
</div>
);

๋ ˆํผ๋Ÿฐ์Šค

Children.count(children)

Children.count(children)๋Š” children ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์˜ ์ž์‹ ์š”์†Œ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

import { Children } from 'react';

function RowList({ children }) {
return (
<>
<h1>Total rows: {Children.count(children)}</h1>
...
</>
);
}

์•„๋ž˜ ์˜ˆ์‹œ ๋ณด๊ธฐ

ํŒŒ๋ผ๋ฏธํ„ฐ

  • children: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ children prop์˜ ๊ฐ’.

๋ฐ˜ํ™˜๊ฐ’

children ๋‚ด๋ถ€ ๋…ธ๋“œ์˜ ์ˆ˜.

์ฃผ์˜ ์‚ฌํ•ญ

  • ๋นˆ ๋…ธ๋“œ(null, undefined ํ˜น์€ Boolean), ๋ฌธ์ž์—ด, ์ˆซ์ž, React ์—˜๋ฆฌ๋จผํŠธ๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐ์—ด ์ž์ฒด๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ ๋ฐฐ์—ด์˜ ์ž์‹ ์š”์†Œ๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. React ์—˜๋ฆฌ๋จผํŠธ์˜ ํ•˜์œ„ ์š”์†Œ๋Š” ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. React ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์œผ๋ฉฐ ์ž์‹ ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Fragments ์—ญ์‹œ ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Children.forEach(children, fn, thisArg?)

Children.forEach(children, fn, thisArg?)๋Š” children ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์˜ ๋ชจ๋“  ์ž์‹ ์š”์†Œ์— ๋Œ€ํ•ด ํŠน์ • ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

import { Children } from 'react';

function SeparatorList({ children }) {
const result = [];
Children.forEach(children, (child, index) => {
result.push(child);
result.push(<hr key={index} />);
});
// ...

์•„๋ž˜ ์˜ˆ์‹œ ๋ณด๊ธฐ

ํŒŒ๋ผ๋ฏธํ„ฐ

  • children: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ children prop์˜ ๊ฐ’.
  • fn: ๋ฐฐ์—ด์˜forEach ๋ฉ”์„œ๋“œ ์ฝœ๋ฐฑ์ฒ˜๋Ÿผ ๊ฐ ์ž์‹ ์š”์†Œ์—์„œ ์‹คํ–‰ํ•  ํ•จ์ˆ˜. ์ž์‹ ์š”์†Œ๋ฅผ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ, ์ธ๋ฑ์Šค๋ฅผ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค๋Š” 0์—์„œ ์‹œ์ž‘ํ•ด์„œ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • optional thisArg: fn ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์‚ฌ์šฉ๋  this์˜ ๊ฐ’. ์ƒ๋žต ์‹œ undefined๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

Children.forEach๋Š” undefined๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜ ์‚ฌํ•ญ

  • ๋นˆ ๋…ธ๋“œ(null, undefined ํ˜น์€ Boolean), ๋ฌธ์ž์—ด, ์ˆซ์ž, React ์—˜๋ฆฌ๋จผํŠธ๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐ์—ด ์ž์ฒด๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ ๋ฐฐ์—ด์˜ ์ž์‹ ์š”์†Œ๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. React ์—˜๋ฆฌ๋จผํŠธ์˜ ํ•˜์œ„ ์š”์†Œ๋Š” ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. React ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์œผ๋ฉฐ ์ž์‹ ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Fragments ์—ญ์‹œ ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Children.map(children, fn, thisArg?)

Children.map(children, fn, thisArg?)์€ children ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์—์„œ ๊ฐ ์ž์‹ ์š”์†Œ๋ฅผ ๋งคํ•‘ํ•˜๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

import { Children } from 'react';

function RowList({ children }) {
return (
<div className="RowList">
{Children.map(children, child =>
<div className="Row">
{child}
</div>
)}
</div>
);
}

์•„๋ž˜ ์˜ˆ์‹œ ๋ณด๊ธฐ

ํŒŒ๋ผ๋ฏธํ„ฐ

  • children: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ children prop์˜ ๊ฐ’.
  • fn: ๋ฒ ์—ด์˜ map ๋ฉ”์„œ๋“œ ์ฝœ๋ฐฑ๊ฐ™์€ ๋งคํ•‘ ํ•จ์ˆ˜. ์ž์‹ ์š”์†Œ๋ฅผ ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ, ์ธ๋ฑ์Šค๋ฅผ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์ธ๋ฑ์Šค๋Š” 0์—์„œ ์‹œ์ž‘ํ•ด์„œ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๋Š” ๋นˆ ๋…ธ๋“œ(null, undefined ํ˜น์€ Boolean), ๋ฌธ์ž์—ด, ์ˆซ์ž, React ์—˜๋ฆฌ๋จผํŠธ ํ˜น์€ ๋‹ค๋ฅธ React ๋…ธ๋“œ์˜ ๋ฐฐ์—ด๊ณผ ๊ฐ™์€ React ๋…ธ๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • optional thisArg: fn ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์‚ฌ์šฉ๋  this์˜ ๊ฐ’. ์ƒ๋žต์‹œ undefined๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜๊ฐ’

children์ด null์ด๊ฑฐ๋‚˜ undefined์ผ ๋• ํ•ด๋‹น ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ fn ํ•จ์ˆ˜์—์„œ ๋ฐ˜ํ™˜ํ•œ ๋…ธ๋“œ๋“ค๋กœ ๊ตฌ์„ฑ๋œ ํ‰๋ฉด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋œ ๋ฐฐ์—ด์€ null๊ณผ undefined๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋ฐ˜ํ™˜๋œ ๋…ธ๋“œ๋ฅผ ๋ชจ๋‘ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜ ์‚ฌํ•ญ

  • ๋นˆ ๋…ธ๋“œ(null, undefined ํ˜น์€ Boolean), ๋ฌธ์ž์—ด, ์ˆซ์ž, React ์—˜๋ฆฌ๋จผํŠธ๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐ์—ด ์ž์ฒด๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ ๋ฐฐ์—ด์˜ ์ž์‹ ์š”์†Œ๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. React ์—˜๋ฆฌ๋จผํŠธ์˜ ํ•˜์œ„ ์š”์†Œ๋Š” ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. React ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์œผ๋ฉฐ ์ž์‹ ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Fragments ์—ญ์‹œ ์ˆœํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • fn์—์„œ key๋ฅผ ๊ฐ€์ง„ ์—˜๋ฆฌ๋จผํŠธ(ํ˜น์€ ์—˜๋ฆฌ๋จผํŠธ์˜ ๋ฐฐ์—ด)์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฐ˜ํ™˜๋œ ์—˜๋ฆฌ๋จผํŠธ์˜ key๋Š” children์˜ ์›๋ณธ ํ•ญ๋ชฉ์˜ key์™€ ์ž๋™์œผ๋กœ ๊ฒฐํ•ฉ๋ฉ๋‹ˆ๋‹ค. fn์—์„œ ๋ฐฐ์—ด๋กœ ์—ฌ๋Ÿฌ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ, ๊ฐ ์—˜๋ฆฌ๋จผํŠธ์˜ key๋Š” ์„œ๋กœ ๊ฐ„์—๋งŒ ๊ณ ์œ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.


Children.only(children)

Children.only(children)์€ children์ด ๋‹จ์ผ React ์—˜๋ฆฌ๋จผํŠธ์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

function Box({ children }) {
const element = Children.only(children);
// ...

ํŒŒ๋ผ๋ฏธํ„ฐ

  • children: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ children prop์˜ ๊ฐ’.

๋ฐ˜ํ™˜๊ฐ’

children์ด ์œ ํšจํ•œ ์—˜๋ฆฌ๋จผํŠธ๋ผ๋ฉด ๊ทธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด, ์—๋Ÿฌ๋ฅผ throwํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜ ์‚ฌํ•ญ

  • ์ด ๋ฉ”์„œ๋“œ๋Š” children์œผ๋กœ ๋ฐฐ์—ด (์˜ˆ๋ฅผ ๋“ค์–ด Children.map์˜ ๋ฐ˜ํ™˜ ๊ฐ’)์„ ๋„˜๊ธฐ๋ฉด ํ•ญ์ƒ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด children์€ ๋‹จ์ผ ์—˜๋ฆฌ๋จผํŠธ์˜ ๋ฐฐ์—ด์ด ์•„๋‹ˆ๋ผ ๋‹จ์ผ React ์—˜๋ฆฌ๋จผํŠธ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Children.toArray(children)

Children.toArray(children)์€ children ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋กœ๋ถ€ํ„ฐ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

import { Children } from 'react';

export default function ReversedList({ children }) {
const result = Children.toArray(children);
result.reverse();
// ...

ํŒŒ๋ผ๋ฏธํ„ฐ

  • children: ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ›์€ children prop์˜ ๊ฐ’.

๋ฐ˜ํ™˜๊ฐ’

children์— ์†ํ•œ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ํ‰๋ฉด ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜ ์‚ฌํ•ญ

  • ๋นˆ ๋…ธ๋“œ(null, undefined, ํ˜น์€ Booleans)๋Š” ๋ฐ˜ํ™˜๋œ ๋ฐฐ์—ด์—์„œ ์ƒ๋žต๋ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋œ ์—˜๋ฆฌ๋จผํŠธ์˜ key๋Š” ๊ธฐ์กด ์—˜๋ฆฌ๋จผํŠธ์˜ key, ์ค‘์ฒฉ ์ˆ˜์ค€๊ณผ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐ๋˜๋ฏ€๋กœ ๋ฐฐ์—ด์„ ํ‰๋ฉดํ™”ํ•˜๋”๋ผ๋„ ๋™์ž‘์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ๋ฒ•

children ๋ณ€ํ™˜ํ•˜๊ธฐ

Children.map์€ children prop๋กœ ๋ฐ›์€ JSX๋ฅผ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

import { Children } from 'react';

function RowList({ children }) {
return (
<div className="RowList">
{Children.map(children, child =>
<div className="Row">
{child}
</div>
)}
</div>
);
}

์œ„ ์˜ˆ์‹œ์—์„œ RowList๋Š” ๋ชจ๋“  ์ž์‹ ์š”์†Œ๋ฅผ <div className="Row">๋กœ ๊ฐ์‹ธ์ค๋‹ˆ๋‹ค. ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ RowList์— ์„ธ ๊ฐœ์˜ <p> ํƒœ๊ทธ๋ฅผ children prop๋กœ ๋„˜๊ฒจ์ค€๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค.

<RowList>
<p>This is the first item.</p>
<p>This is the second item.</p>
<p>This is the third item.</p>
</RowList>

์œ„์— ๋‚˜์˜จ RowList ๊ตฌํ˜„์„ ํ†ตํ•ด ๋ Œ๋”๋ง ๋œ ์ตœ์ข… ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

<div className="RowList">
<div className="Row">
<p>This is the first item.</p>
</div>
<div className="Row">
<p>This is the second item.</p>
</div>
<div className="Row">
<p>This is the third item.</p>
</div>
</div>

Children.map์€ map()์„ ์‚ฌ์šฉํ•ด ๋ฐฐ์—ด์„ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ, children ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๊ฐ€ ๋ถˆ๋ถ„๋ช…ํ•˜๊ฒŒ ์ทจ๊ธ‰๋œ๋‹ค๋Š” ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋ฐฐ์—ด์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•˜๋”๋ผ๋„ ํ•ญ์ƒ ๋ฐฐ์—ด์ด๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ํŠน์ •ํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์ผ ๊ฒƒ์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— children์„ ๋ณ€ํ™˜ํ•  ๋•Œ๋Š” Children.map์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

import { Children } from 'react';

export default function RowList({ children }) {
  return (
    <div className="RowList">
      {Children.map(children, child =>
        <div className="Row">
          {child}
        </div>
      )}
    </div>
  );
}

Deep Dive

children prop๋Š” ์™œ ํ•ญ์ƒ ๋ฐฐ์—ด์ด ์•„๋‹Œ๊ฐ€์š”?

React์—์„œ children prop๋Š” ๋ถˆ๋ถ„๋ช…ํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋กœ ์ทจ๊ธ‰๋ฉ๋‹ˆ๋‹ค. children์ด ๊ตฌ์กฐํ™”๋œ ๋ฐฉ์‹์— ์˜์กดํ•  ์ˆ˜ ์—†๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ๋ณ€ํ™˜ํ•˜๊ฑฐ๋‚˜ ํ•„ํ„ฐ๋งํ•˜๊ฑฐ๋‚˜ ๊ฐœ์ˆ˜๋ฅผ ์„ธ๊ธฐ ์œ„ํ•ด์„œ๋Š” Children ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ children ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐฐ์—ด๋กœ ํ‘œํ˜„๋˜๊ณ ๋Š” ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งŒ์•ฝ ํ•˜๋‚˜์˜ ์ž์‹๋งŒ ์žˆ๋‹ค๋ฉด React๋Š” ๋ถˆํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐฐ์—ด์„ ์ถ”๊ฐ€๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. children prop์— ์ง์ ‘ ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ  Children ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์‹ค์ œ๋กœ React๊ฐ€ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ–ˆ๋”๋ผ๋„ ์ฝ”๋“œ๋Š” ๊นจ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

children์ด ๋ฐฐ์—ด์ด๋”๋ผ๋„ Children.map์„ ์œ ์šฉํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Children.map์€ ๋ฐ˜ํ™˜๋œ ์—˜๋ฆฌ๋จผํŠธ์˜ key๋ฅผ ์ „๋‹ฌ๋ฐ›์€ children์˜ key์™€ ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์œ„ ์˜ˆ์‹œ์ฒ˜๋Ÿผ ๊ฐ์‹ธ์ง€๋”๋ผ๋„ ์›๋ณธ JSX ์ž์‹ ์š”์†Œ๋Š” key๋ฅผ ์žƒ์–ด๋ฒ„๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฃผ์˜ํ•˜์„ธ์š”!

children ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋Š” JSX๋กœ ์ „๋‹ฌ๋œ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ RowList๊ฐ€ ๋ฐ›์€ children์—๋Š” ์„ธ ๊ฐœ๊ฐ€ ์•„๋‹Œ ๋‘ ๊ฐœ์˜ ์•„์ดํ…œ๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  1. <p>This is the first item.</p>
  2. <MoreRows />

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ๋Š” ๋‘ ๊ฐœ์˜ ๋ž˜ํผ๋งŒ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

import RowList from './RowList.js';

export default function App() {
  return (
    <RowList>
      <p>This is the first item.</p>
      <MoreRows />
    </RowList>
  );
}

function MoreRows() {
  return (
    <>
      <p>This is the second item.</p>
      <p>This is the third item.</p>
    </>
  );
}

children์„ ์กฐ์ž‘ํ•  ๋•Œ <MoreRows />์™€ ๊ฐ™์€ ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ๋œ ๊ฒฐ๊ณผ์— ์ ‘๊ทผํ•  ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์•ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.


๊ฐ ์ž์‹ ์š”์†Œ์—์„œ ์ฝ”๋“œ ์‹คํ–‰ํ•˜๊ธฐ

Children.forEach๋Š” children ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์˜ ๊ฐ ์ž์‹ ์š”์†Œ๋ฅผ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ’์€ ์—†๊ณ  ๋ฐฐ์—ด์˜ forEach ๋ฉ”์„œ๋“œ์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ž์ฒด ๋ฐฐ์—ด์„ ๊ตฌ์„ฑํ•˜๋Š” ๋“ฑ ์ปค์Šคํ…€ ๋กœ์ง์„ ์‹คํ–‰ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { Children } from 'react';

export default function SeparatorList({ children }) {
  const result = [];
  Children.forEach(children, (child, index) => {
    result.push(child);
    result.push(<hr key={index} />);
  });
  result.pop(); // Remove the last separator
  return result;
}

์ฃผ์˜ํ•˜์„ธ์š”!

์œ„์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ children์„ ์กฐ์ž‘ํ•  ๋•Œ ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ๋œ ๊ฒฐ๊ณผ์— ์ ‘๊ทผํ•  ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์•ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.


children ์นด์šดํŒ…ํ•˜๊ธฐ

Children.count(children)๋Š” ์ž์‹ ์š”์†Œ์˜ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.

import { Children } from 'react';

export default function RowList({ children }) {
  return (
    <div className="RowList">
      <h1 className="RowListHeader">
        Total rows: {Children.count(children)}
      </h1>
      {Children.map(children, child =>
        <div className="Row">
          {child}
        </div>
      )}
    </div>
  );
}

์ฃผ์˜ํ•˜์„ธ์š”!

์œ„์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ children์„ ์กฐ์ž‘ํ•  ๋•Œ ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ๋œ ๊ฒฐ๊ณผ์— ์ ‘๊ทผํ•  ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์•ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.


children ๋ฐฐ์—ด๋กœ ๋ณ‘ํ•ฉํ•˜๊ธฐ

Children.toArray(children)๋Š” children ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ผ๋ฐ˜์ ์ธ JavaScript ๋ฐฐ์—ด๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•ด์„œ filter, sort, reverse์™€ ๊ฐ™์€ ๋ฐฐ์—ด์˜ ๋‚ด์žฅ ๋ฉ”์„œ๋“œ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { Children } from 'react';

export default function ReversedList({ children }) {
  const result = Children.toArray(children);
  result.reverse();
  return result;
}

์ฃผ์˜ํ•˜์„ธ์š”!

์œ„์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ children์„ ์กฐ์ž‘ํ•  ๋•Œ ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ๋œ ๊ฒฐ๊ณผ์— ์ ‘๊ทผํ•  ๋ฐฉ๋ฒ•์€ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋Œ€์•ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.


๋Œ€์•ˆ

์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค!

์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉ๋˜๋Š” Children(๋Œ€๋ฌธ์ž C) API์˜ ๋Œ€์•ˆ์— ๋Œ€ํ•œ ์„ค๋ช…์ž…๋‹ˆ๋‹ค.

import { Children } from 'react';

์†Œ๋ฌธ์ž c์ธ childrenprop์™€ ํ˜ผ๋™ํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. childrenprop๋Š” ์ข‹์€ ๋ฐฉ๋ฒ•์ด๊ณ  ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ ๋…ธ์ถœํ•˜๊ธฐ

Children ๋ฉ”์„œ๋“œ๋กœ ์ž์‹ ์š”์†Œ๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ์ฝ”๋“œ๋Š” ์ทจ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. JSX์—์„œ ์ปดํฌ๋„ŒํŠธ์— ์ž์‹ ์š”์†Œ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐœ๋ณ„ ์ž์‹ ์š”์†Œ๋ฅผ ์กฐ์ž‘ํ•˜๊ฑฐ๋‚˜ ๋ณ€ํ™˜๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•œ ํ•œ Children ๋ฉ”์„œ๋“œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด RowList์˜ ๊ฐ ์ž์‹ ์š”์†Œ๋ฅผ <div className="Row">๋กœ ๊ฐ์‹ธ๋ ค๋ฉด, Row ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‚ด๋ณด๋‚ด๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ row๋ฅผ ์ง์ ‘ ๊ฐ์‹ธ๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList>
      <Row>
        <p>This is the first item.</p>
      </Row>
      <Row>
        <p>This is the second item.</p>
      </Row>
      <Row>
        <p>This is the third item.</p>
      </Row>
    </RowList>
  );
}

Children.map๊ณผ ๋‹ฌ๋ฆฌ ์ด ๋ฐฉ์‹์€ ๋ชจ๋“  ์ž์‹ ์š”์†Œ๋ฅผ ์ž๋™์œผ๋กœ ๊ฐ์‹ธ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Children.map์˜ ์•ž์„  ์˜ˆ์‹œ์™€ ๋‹ฌ๋ฆฌ ๋” ๋งŽ์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”์ถœํ•ด๋„ ๋™์ž‘ํ•œ๋‹ค๋Š” ์ค‘์š”ํ•œ ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด MoreRows ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง์ ‘ ์ถ”์ถœํ•˜๋”๋ผ๋„ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList>
      <Row>
        <p>This is the first item.</p>
      </Row>
      <MoreRows />
    </RowList>
  );
}

function MoreRows() {
  return (
    <>
      <Row>
        <p>This is the second item.</p>
      </Row>
      <Row>
        <p>This is the third item.</p>
      </Row>
    </>
  );
}

<MoreRows />๊ฐ€ ๋‹จ์ผ ์ž์‹ ์š”์†Œ์ด์ž ๋‹จ์ผ row๋กœ ์ทจ๊ธ‰๋˜๊ธฐ ๋•Œ๋ฌธ์— Children.map์€ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


prop๋กœ ๊ฐ์ฒด ๋ฐฐ์—ด ๋ฐ›๊ธฐ

prop๋กœ ๋ช…์‹œ์ ์œผ๋กœ ๋ฐฐ์—ด์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ RowList๋Š” rows ๋ฐฐ์—ด์„ prop๋กœ ๋ฐ›์Šต๋‹ˆ๋‹ค.

import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList rows={[
      { id: 'first', content: <p>This is the first item.</p> },
      { id: 'second', content: <p>This is the second item.</p> },
      { id: 'third', content: <p>This is the third item.</p> }
    ]} />
  );
}

rows๋Š” ์ผ๋ฐ˜์ ์ธ JavaScript ๋ฐฐ์—ด์ด๊ธฐ ๋•Œ๋ฌธ์—, RowList ์ปดํฌ๋„ŒํŠธ๋Š” map๊ณผ ๊ฐ™์€ ๋‚ด์žฅ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ํŒจํ„ด์€ ๊ตฌ์กฐํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž์‹ ์š”์†Œ์™€ ํ•จ๊ป˜ ์ „๋‹ฌํ•  ๋•Œ ๋” ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ TabSwitcher ์ปดํฌ๋„ŒํŠธ๋Š” tabs prop๋กœ ๊ฐ์ฒด ๋ฐฐ์—ด์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.

import TabSwitcher from './TabSwitcher.js';

export default function App() {
  return (
    <TabSwitcher tabs={[
      {
        id: 'first',
        header: 'First',
        content: <p>This is the first item.</p>
      },
      {
        id: 'second',
        header: 'Second',
        content: <p>This is the second item.</p>
      },
      {
        id: 'third',
        header: 'Third',
        content: <p>This is the third item.</p>
      }
    ]} />
  );
}

JSX๋กœ ์ž์‹ ์š”์†Œ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ์™€ ๋‹ฌ๋ฆฌ ์ด๋Ÿฐ ๋ฐฉ์‹์€ ๊ฐ ์•„์ดํ…œ์— header์™€ ๊ฐ™์€ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. tabs๊ฐ€ ๋ฐฐ์—ด ๊ตฌ์กฐ์ด๊ณ  ์ง์ ‘ ๋‹ค๋ค„์ง€๊ธฐ ๋•Œ๋ฌธ์— Children ๋ฉ”์„œ๋“œ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


render prop๋กœ ๋ Œ๋”๋ง ์ปค์Šคํ…€ํ•˜๊ธฐ

๋ชจ๋“  ๊ฐœ๋ณ„ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด JSX๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋Œ€์‹  JSX๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ํ•„์š”ํ•  ๋•Œ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ App ์ปดํฌ๋„ŒํŠธ๋Š” renderContent ํ•จ์ˆ˜๋ฅผ TabSwitcher ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. TabSwitcher ์ปดํฌ๋„ŒํŠธ๋Š” ์„ ํƒ๋œ ํƒญ์— ๋Œ€ํ•ด์„œ๋งŒ renderContent๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

import TabSwitcher from './TabSwitcher.js';

export default function App() {
  return (
    <TabSwitcher
      tabIds={['first', 'second', 'third']}
      getHeader={tabId => {
        return tabId[0].toUpperCase() + tabId.slice(1);
      }}
      renderContent={tabId => {
        return <p>This is the {tabId} item.</p>;
      }}
    />
  );
}

renderContent์™€ ๊ฐ™์ด ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ผ๋ถ€๋ฅผ ์–ด๋–ป๊ฒŒ ๋ Œ๋”๋งํ• ์ง€ ์ •์˜ํ•˜๋Š” prop๋ฅผ render prop๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํŠน๋ณ„ํ•œ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‹จ์ง€ ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜์˜ prop์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

Render props๋Š” ํ•จ์ˆ˜์ด๋ฏ€๋กœ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ์—์„œ RowList ์ปดํฌ๋„ŒํŠธ๋Š” ๊ฐ row์˜ id์™€ index๋ฅผ renderRow์— render prop๋กœ ์ „๋‹ฌํ•˜๊ณ , index๊ฐ€ ์ง์ˆ˜์ธ row๋ฅผ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค.

import { RowList, Row } from './RowList.js';

export default function App() {
  return (
    <RowList
      rowIds={['first', 'second', 'third']}
      renderRow={(id, index) => {
        return (
          <Row isHighlighted={index % 2 === 0}>
            <p>This is the {id} item.</p>
          </Row> 
        );
      }}
    />
  );
}

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์™€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž์‹ ์š”์†Œ๋ฅผ ์ง์ ‘ ์กฐ์ž‘ํ•˜์ง€ ์•Š๊ณ ๋„ ํšจ๊ณผ์ ์œผ๋กœ ํ˜‘๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.


๋ฌธ์ œ ํ•ด๊ฒฐ

์ปค์Šคํ…€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ „๋‹ฌํ–ˆ์„ ๋•Œ Children ๋ฉ”์„œ๋“œ๊ฐ€ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ

RowList์— ๋‘ ๊ฐœ์˜ ์ž์‹ ์š”์†Œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ „๋‹ฌํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค.

<RowList>
<p>First item</p>
<MoreRows />
</RowList>

RowList ๋‚ด๋ถ€์—์„œ Children.count(children)๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค๋ฉด ๊ฒฐ๊ณผ๋Š” 2์ž…๋‹ˆ๋‹ค. MoreRows๊ฐ€ 10๊ฐœ์˜ ๋‹ค๋ฅธ ์š”์†Œ๋ฅผ ๋ Œ๋”๋งํ•˜๊ฑฐ๋‚˜ null์„ ๋ฐ˜ํ™˜ํ•˜๋”๋ผ๋„, Children.count(children)๋Š” 2์ž…๋‹ˆ๋‹ค. RowList ๊ด€์ ์—์„œ๋Š” ๊ทธ๊ฒƒ์ด ๋ฐ›์€ JSX๋งŒ ๊ณ ๋ คํ•  ๋ฟ MoreRows ์ปดํฌ๋„ŒํŠธ์˜ ๋‚ด๋ถ€๋Š” ๊ณ ๋ คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฐ ์ œ์•ฝ๋•Œ๋ฌธ์— ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”์ถœํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— Children ๋Œ€์‹  ๋Œ€์•ˆ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.