diff --git a/July/article/How-React-Server-Components-work:an-in-depth-guide.md b/July/article/How-React-Server-Components-work:an-in-depth-guide.md new file mode 100644 index 0000000..e789dce --- /dev/null +++ b/July/article/How-React-Server-Components-work:an-in-depth-guide.md @@ -0,0 +1,572 @@ +## ๐Ÿ”— [How React server components work: an in-depth guide](https://www.plasmic.app/blog/how-react-server-components-work) + +### ๐Ÿ—“๏ธ ๋ฒˆ์—ญ ๋‚ ์งœ: 2024.07.08 + +### ๐Ÿงš ๋ฒˆ์—ญํ•œ ํฌ๋ฃจ: ๋ฒ„๊ฑด๋””(์ „ํƒœํ—Œ) + +--- + +React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ(RSC)๋Š” React 18์—์„œ ์‹คํ—˜์ ์œผ๋กœ ๋„์ž…๋œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์œผ๋กœ, ํŽ˜์ด์ง€ ๋กœ๋“œ ์„ฑ๋Šฅ, ๋ฒˆ๋“ค ํฌ๊ธฐ, ๊ทธ๋ฆฌ๊ณ  React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ๋ฐฉ์‹์— ์—„์ฒญ๋‚œ ์˜ํ–ฅ์„ ๋ฏธ์น  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€๋ฉ๋‹ˆ๋‹ค. + +์ €ํฌ Plasmic์€ React์šฉ ์‹œ๊ฐ์  ๋นŒ๋”๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ํŠนํžˆ ์„ฑ๋Šฅ ์ค‘์š”ํ•œ ๋งˆ์ผ€ํŒ… ๋ฐ ์ „์ž์ƒ๊ฑฐ๋ž˜ ์‚ฌ์ดํŠธ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ณ ๊ฐ๋“ค์—๊ฒŒ ๋งค์šฐ ์ค‘์š”ํ•œ React ์„ฑ๋Šฅ ๊ฐœ์„ ์— ํฐ ๊ด€์‹ฌ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด์— React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด ๊นŠ์ด ํŒŒํ—ค์ณ๋ณด์•˜์œผ๋ฉฐ, ๊ทธ ๋™์ž‘ ์›๋ฆฌ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ณ  ๊ณต์œ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. + +๋˜ํ•œ [ํŠธ์œ— ์š”์•ฝ](https://www.reddit.com/r/reactjs/comments/s8r0ve/how_react_server_components_work_an_indepth_guide/)์„ ๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +## ๋ฆฌ์•กํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฌด์—‡์ผ๊นŒ์š” ? + +๋ฆฌ์•กํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ (RSC)๋Š” ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)๊ฐ€ ํ˜‘๋ ฅํ•˜์—ฌ React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. + +์ผ๋ฐ˜์ ์œผ๋กœ React ์š”์†Œ ํŠธ๋ฆฌ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ React ์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌ์„ฑ๋˜์–ด ํŽ˜์ด์ง€๋ฅผ ๋ Œ๋”๋งํ•˜๋Š”๋ฐ, RSC๋Š” ์ด ํŠธ๋ฆฌ์˜ ์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•˜๊ณ , ์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. + +์ด๋Š” ๊ธฐ์กด์˜ React ๊ฐœ๋ฐœ ๋ฐฉ์‹์„ ํฌ๊ฒŒ ๋ฐ”๊พธ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. + +React ํŒ€์ด ์ œ์‹œํ•œ ๊ฐ„๋žตํ•œ ๊ทธ๋ฆผ์—์„œ๋„ ์ด ๋ชฉํ‘œ๊ฐ€ ์ž˜ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค: ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋˜๋Š” ์ฃผํ™ฉ์ƒ‰ ์ปดํฌ๋„ŒํŠธ์™€ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง๋˜๋Š” ํŒŒ๋ž€์ƒ‰ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ˜ผํ•ฉ๋œ React ํŠธ๋ฆฌ์ž…๋‹ˆ๋‹ค. + +![](https://www.plasmic.app/blog/static/images/react-server-components.png) + +### ์ด๊ฑด ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง(SSR) ์•„๋‹Œ๊ฐ€์š” ? + +**๋ฆฌ์•กํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” SSR์ด ์•„๋‹™๋‹ˆ๋‹ค!** + +๋‘ ๊ธฐ์ˆ  ๋ชจ๋‘ "์„œ๋ฒ„"๋ผ๋Š” ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ์„œ๋ฒ„์—์„œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ, ๋ณ„๋„์˜ ๊ฐœ๋…์ด๋ฉฐ ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. + +SSR์€ React ํŠธ๋ฆฌ๋ฅผ ์›์‹œ HTML๋กœ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•œ ํ™˜๊ฒฝ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๋Š” ๋ฐ˜๋ฉด, RSC๋Š” ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ˜‘๋ ฅํ•˜์—ฌ ํŠน์ • ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„œ๋ฒ„ ๋˜๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. + +SSR์€ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ์•Š๊ณ  ๋™์ผํ•˜๊ฒŒ ๋ Œ๋”๋งํ•˜์ง€๋งŒ, RSC๋Š” ์„œ๋ฒ„์—์„œ ์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ , ๋‚˜๋จธ์ง€๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋งํ•˜๋Š” ์ ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. + +RSC๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” SSR์„ ์‚ฌ์šฉํ•  ํ•„์š”๋Š” ์—†์œผ๋ฉฐ, ๊ทธ ๋ฐ˜๋Œ€๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. + +๋ฌผ๋ก  SSR๊ณผ RSC๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์„œ๋ฒ„์‚ฌ์ด๋“œ ๋ Œ๋”๋ง๊ณผ ํ•จ๊ป˜ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ ์ ˆํ•˜๊ฒŒ ๋ Œ๋”๋งํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. + +ํ–ฅํ›„ ํฌ์ŠคํŠธ์—์„œ๋Š” ์ด ๋‘ ๊ธฐ์ˆ ์ด ์–ด๋–ป๊ฒŒ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ๋” ์ž์„ธํžˆ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. + +ํ•˜์ง€๋งŒ ํ˜„์žฌ๋Š” SSR์„ ๋ฌด์‹œํ•˜๊ณ  RSC์—๋งŒ ์ง‘์ค‘ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. + +## ์šฐ๋ฆฌ๋Š” ์ด๊ฑธ ์™œ ์›ํ•˜๊ฒŒ ๋ ๊นŒ์š” ? + +๋ฆฌ์•กํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋„์ž…๋˜๊ธฐ ์ „์—๋Š” ๋ชจ๋“  ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ "ํด๋ผ์ด์–ธํŠธ" ์ปดํฌ๋„ŒํŠธ๋กœ, ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. + +๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฆฌ์•กํŠธ ํŽ˜์ด์ง€๋ฅผ ๋ฐฉ๋ฌธํ•˜๋ฉด ํ•„์š”ํ•œ ๋ชจ๋“  ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์˜ ์ฝ”๋“œ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ , ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ DOM์— ๋ Œ๋”๋งํ•˜๊ฑฐ๋‚˜(SSR์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ DOM์„ ํ•˜์ด๋“œ๋ ˆ์ด์…˜) ํ•ฉ๋‹ˆ๋‹ค. + +๋ธŒ๋ผ์šฐ์ €์—์„œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€ ์ด์œ ๋Š” ๋ฆฌ์•กํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. + +์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์„ค์น˜ํ•˜๊ณ , ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๋ฉฐ, ์ด๋ฒคํŠธ์— ๋”ฐ๋ผ ๋ฆฌ์•กํŠธ ํŠธ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ , ํšจ์œจ์ ์œผ๋กœ DOM์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ทธ๋ ‡๋‹ค๋ฉด ์™œ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง์„ ํ•ด์•ผ ํ• ๊นŒ์š”? + +๋ธŒ๋ผ์šฐ์ €๋ฅผ ๋„˜์–ด์„œ์„œ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง ํ•˜๋Š” ๊ฒƒ์˜ ๋ช‡๋ช‡ ์žฅ์ ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค. + +- ์„œ๋ฒ„๋Š” ๋ฐ์ดํ„ฐ ์†Œ์Šค์— ์ง์ ‘์ ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, GraphQL ์—”๋“œํฌ์ธํŠธ, ํŒŒ์ผ ์‹œ์Šคํ…œ ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. + ์„œ๋ฒ„๋Š” ๊ณต์šฉ API ์—”๋“œํฌ์ธํŠธ๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š๊ณ ๋„ ์ง์ ‘ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ณดํ†ต ๋ฐ์ดํ„ฐ ์†Œ์Šค์™€ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๋” ๊ฐ€๊นŒ์šด ์œ„์น˜์— ์žˆ์–ด ๋ธŒ๋ผ์šฐ์ €๋ณด๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ ๋” ๋น ๋ฅด๊ฒŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +- ์„œ๋ฒ„๋Š” ๋งˆํฌ๋‹ค์šด์„ HTML๋กœ ๋ Œ๋”๋งํ•˜๋Š” npm ํŒจํ‚ค์ง€์™€ ๊ฐ™์€ "๋ฌด๊ฑฐ์šด" ์ฝ”๋“œ ๋ชจ๋“ˆ์„ ์ €๋ ดํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + ๋ธŒ๋ผ์šฐ์ €๋Š” ์ด๋Ÿฌํ•œ ์˜์กด์„ฑ์„ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค๋กœ ๋‹ค์šด๋กœ๋“œํ•ด์•ผ ํ•˜์ง€๋งŒ, ์„œ๋ฒ„๋Š” ๋งค๋ฒˆ ์ด๋Ÿฌํ•œ ์˜์กด์„ฑ์„ ๋‹ค์šด๋กœ๋“œํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. + +๊ฐ„๋‹จํžˆ ๋งํ•ด, **๋ฆฌ์•กํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋ฒ„์™€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ฐ์ž์˜ ์žฅ์ ์„ ์ตœ๋Œ€ํ•œ ๋ฐœํœ˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.** ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ์™€ ์ฝ˜ํ…์ธ  ๋ Œ๋”๋ง์— ์ง‘์ค‘ํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ  ์ƒํ˜ธ์ž‘์šฉ์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +๊ทธ ๊ฒฐ๊ณผ, ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์†๋„๊ฐ€ ๋นจ๋ผ์ง€๊ณ  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค ํฌ๊ธฐ๊ฐ€ ์ž‘์•„์ง€๋ฉฐ, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์ด ๊ฐœ์„ ๋ฉ๋‹ˆ๋‹ค. + +## ์ „์ฒด์ ์ธ ๊ทธ๋ฆผ + +์ด ์ž‘์—…์ด ์–ด๋–ป๊ฒŒ ์ด๋ฃจ์–ด์ง€๋Š”์ง€ ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•ด๋ด…์‹œ๋‹ค. + +์ œ ์•„์ด๋“ค์€ ์ปต์ผ€์ดํฌ ์žฅ์‹์„ ๋งค์šฐ ์ข‹์•„ํ•˜์ง€๋งŒ, ๊ตฝ๋Š” ๊ณผ์ •์—๋Š” ๋ณ„๋กœ ํฅ๋ฏธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. + +๋งŒ์•ฝ ์•„์ด๋“ค์—๊ฒŒ ์ฒ˜์Œ๋ถ€ํ„ฐ ์ปต์ผ€์ดํฌ๋ฅผ ๋งŒ๋“ค๊ณ  ์žฅ์‹ํ•˜๋ผ๊ณ  ํ•œ๋‹ค๋ฉด (๊ท€์—ฝ๊ธด ํ•˜๊ฒ ์ง€๋งŒ) ์ •๋ง ํฐ์ผ์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +์ €๋Š” ์•„์ด๋“ค์—๊ฒŒ ๋ฐ€๊ฐ€๋ฃจ์™€ ์„คํƒ•, ๋ฒ„ํ„ฐ๋ฅผ ์ฃผ๊ณ  ์˜ค๋ธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋ฉฐ, ๋งŽ์€ ์„ค๋ช…์„ ์ฝ์–ด์ฃผ๊ณ  ํ•˜๋ฃจ ์ข…์ผ ๊ฑธ๋ฆด ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฌ๋‚˜ ์ œ๊ฐ€ ๋ฏธ๋ฆฌ ์ผ๋ถ€ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค๋ฉด, ์ฆ‰ ์ปต์ผ€์ดํฌ๋ฅผ ๊ตฝ๊ณ  ์•„์ด์‹ฑ์„ ๋งŒ๋“ค์–ด ์•„์ด๋“ค์—๊ฒŒ ์ฃผ๋ฉด, ์•„์ด๋“ค์€ ๋” ๋นจ๋ฆฌ ์žฌ๋ฏธ์žˆ๋Š” ์žฅ์‹ ์ž‘์—…์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! + +๊ฒŒ๋‹ค๊ฐ€ ์˜ค๋ธ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฑฑ์ •๋„ ํ•˜์ง€ ์•Š์•„๋„ ๋˜์ฃ . ์ •๋ง ์ข‹์€ ์ƒํ™ฉ์ด์ฃ ! + +![](https://www.plasmic.app/blog/static/images/cake.jpg) + +๋ฆฌ์•กํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์ด๋Ÿฌํ•œ ์ž‘์—… ๋ถ„๋‹ด์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. + +์ฆ‰, ์„œ๋ฒ„๊ฐ€ ์ž˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์„ ๋ฏธ๋ฆฌ ์ฒ˜๋ฆฌํ•œ ํ›„, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋‚˜๋จธ์ง€ ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋„๋ก ๋„˜๊ธฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ ๋„˜๊ฒจ์ค˜์•ผ ํ•  ๊ฒƒ๋“ค์ด ์ค„์–ด๋“ญ๋‹ˆ๋‹ค. + +์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฐ€๊ฐ€๋ฃจ ํ•œ ๋ด‰์ง€์™€ ์˜ค๋ธ ์ „์ฒด๋ฅผ ๋„˜๊ธฐ๋Š” ๋Œ€์‹ , 12๊ฐœ์˜ ์ž‘์€ ์ปต์ผ€์ดํฌ๋ฅผ ๋„˜๊ธฐ๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค! + +์—ฌ๋Ÿฌ๋ถ„์˜ ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ๋ฆฌ์•กํŠธ ํŠธ๋ฆฌ๋ฅผ ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค. + +์ผ๋ถ€ ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋˜๊ณ , ์ผ๋ถ€๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. + +์ด๋Ÿฌํ•œ ๊ณ ์ˆ˜์ค€์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋Š” ์ „๋žต์„ ๋‹จ์ˆœํ™”ํ•ด์„œ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค: + +์„œ๋ฒ„๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ‰์†Œ์ฒ˜๋Ÿผ "๋ Œ๋”๋ง"ํ•˜์—ฌ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ `div`๋‚˜ `p` ๊ฐ™์€ ๋„ค์ดํ‹ฐ๋ธŒ HTML ์š”์†Œ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฌ๋‚˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜๋Š” "ํด๋ผ์ด์–ธํŠธ" ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋‚˜๋ฉด, ์„œ๋ฒ„๋Š” ๊ทธ ์ž๋ฆฌ์— ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์™€ ์†์„ฑ(props)์„ ์ฑ„์šฐ๊ธฐ ์œ„ํ•œ ์ง€์นจ๊ณผ ํ•จ๊ป˜ `ํ”Œ๋ ˆ์ด์Šคํ™€๋”`๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. + +๊ทธ ๋‹ค์Œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด ์ถœ๋ ฅ์„ ๋ฐ›์•„์„œ, ๊ทธ ํ”Œ๋ ˆ์ด์Šคํ™€๋”๋ฅผ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์ฑ„์šฐ๋ฉด ๋๋‚ฉ๋‹ˆ๋‹ค! + +**์‹ค์ œ๋กœ๋Š” ์ด๋ ‡๊ฒŒ ๊ฐ„๋‹จํ•˜์ง€ ์•Š์ง€๋งŒ,** ์ด์ œ ๊ณง ๋ณต์žกํ•œ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. + +ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๊ณ ์ˆ˜์ค€์˜ ๊ทธ๋ฆผ์„ ๋จธ๋ฆฟ์†์— ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์€ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค! + +## ์„œ๋ฒ„-ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ๊ตฌ๋ถ„ + +๋จผ์ €, ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”? ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๊ฐ€ "์„œ๋ฒ„์šฉ"์ด๊ณ  ์–ด๋–ค ๊ฒƒ์ด "ํด๋ผ์ด์–ธํŠธ์šฉ"์ธ์ง€ ์–ด๋–ป๊ฒŒ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? + +๋ฆฌ์•กํŠธ ํŒ€์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž‘์„ฑ๋œ ํŒŒ์ผ์˜ ํ™•์žฅ์ž์— ๋”ฐ๋ผ ์ด๋ฅผ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค. + +ํŒŒ์ผ์ด `.server.jsx`๋กœ ๋๋‚˜๋ฉด ๊ทธ ํŒŒ์ผ์—๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๊ณ , `.client.jsx`๋กœ ๋๋‚˜๋ฉด ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. + +ํ™•์žฅ์ž๊ฐ€ ๋‘˜ ๋‹ค ์•„๋‹Œ ๊ฒฝ์šฐ, ๊ทธ ํŒŒ์ผ์—๋Š” ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ ๋ชจ๋‘์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด ์ •์˜๋Š” ์‹ค์šฉ์ ์ž…๋‹ˆ๋‹ค. + +์‚ฌ๋žŒ๋“ค๊ณผ ๋ฒˆ๋“ค๋Ÿฌ ๋ชจ๋‘๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‰ฝ๊ฒŒ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +ํŠนํžˆ ๋ฒˆ๋“ค๋Ÿฌ๋Š” ํŒŒ์ผ ์ด๋ฆ„์„ ๊ฒ€์‚ฌํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ณง ์•Œ๊ฒŒ ๋˜๊ฒ ์ง€๋งŒ, ๋ฒˆ๋“ค๋Ÿฌ๋Š” ๋ฆฌ์•กํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ(RSC)๋ฅผ ์ž‘๋™์‹œํ‚ค๋Š” ๋ฐ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. + +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋ฒ„์—์„œ ์‹คํ–‰๋˜๊ณ  ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์—๋Š” ๋งŽ์€ ์ œํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค. + +๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ **ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†๋‹ค๋Š” ์ **์ž…๋‹ˆ๋‹ค. + +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰๋  ์ˆ˜ ์—†์œผ๋ฉฐ, ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ์˜์กดํ•˜๊ฒŒ ๋˜๋ฉด, ๋ธŒ๋ผ์šฐ์ € ๋ฒˆ๋“ค์— ์ด๋Ÿฌํ•œ ํ—ˆ์šฉ ๋˜์ง€ ์•Š๋Š” ์˜์กด์„ฑ์„ ๋Œ์–ด์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. + +์ด ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„์€ ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ ํ˜•์‹์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. + +```tsx +// ClientComponent.client.jsx +// NOT OK: +import ServerComponent from "./ServerComponent.server"; +export default function ClientComponent() { + return ( +
+ +
+ ); +} +``` + +ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ importํ•  ์ˆ˜ ์—†๊ณ , ๋”ฐ๋ผ์„œ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•  ์ˆ˜ ์—†๋Š”๋ฐ, ์–ด๋–ป๊ฒŒ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„ž์—ฌ ์žˆ๋Š” React ํŠธ๋ฆฌ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‚˜์š”? + +์–ด๋–ป๊ฒŒ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ(ํŒŒ๋ž€ ์ ) ์•„๋ž˜์— ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ(์ฃผํ™ฉ ์ )๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‚˜์š”? + +![](https://www.plasmic.app/blog/static/images/react-server-components.png) + +ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ importํ•˜๊ณ  ๋ Œ๋”๋งํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ, ์—ฌ์ „ํžˆ ์ปดํฌ์ง€์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ฆ‰, ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ถˆํˆฌ๋ช…ํ•œ `ReactNode` ํ˜•ํƒœ์˜ `props`๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ReactNode๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์— ์˜ํ•ด ๋ Œ๋”๋ง๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด: + +```tsx +// ClientComponent.client.jsx +export default function ClientComponent({ children }) { + return ( +
+

Hello from client land

+ {children} +
+ ); +} + +// ServerComponent.server.jsx +export default function ServerComponent() { + return Hello from server land; +} + +// OuterServerComponent.server.jsx +// OuterServerComponent๋Š” ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ชจ๋‘ ์ธ์Šคํ„ด์Šคํ™”ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, +// ๋ฅผ ClientComponent์˜ children prop์œผ๋กœ ์ „๋‹ฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + +import ClientComponent from "./ClientComponent.client"; +import ServerComponent from "./ServerComponent.server"; +export default function OuterServerComponent() { + return ( + + + + ); +} +``` + +์ด ์ œํ•œ์€ RSC๋ฅผ ๋” ์ž˜ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ์‹์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์น  ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +## - RSC ๋ Œ๋”๋ง์˜ ๊ณผ์ • + +React ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์‹ค์ œ๋กœ ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ•˜๋Š”์ง€ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. + +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๊ธฐ์„œ ๋ชจ๋“  ๊ฒƒ์„ ์ดํ•ดํ•  ํ•„์š”๋Š” ์—†์ง€๋งŒ, ์ž‘๋™ ๋ฐฉ์‹์„ ์ง๊ด€์ ์œผ๋กœ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +## 1. ์„œ๋ฒ„๊ฐ€ ๋ Œ๋”๋ง ์š”์ฒญ์„ ๋ฐ›์Œ + +์„œ๋ฒ„๋Š” ์ผ๋ถ€ ๋ Œ๋”๋ง์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋ฏ€๋กœ RSC๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŽ˜์ด์ง€์˜ ์‹œ์ž‘์€ ํ•ญ์ƒ ์„œ๋ฒ„์—์„œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. + +์ด๋Š” React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•œ API ํ˜ธ์ถœ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. + +์ด "๋ฃจํŠธ" ์ปดํฌ๋„ŒํŠธ๋Š” ํ•ญ์ƒ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์ด๋ฉฐ, ์ด๋Š” ๋‹ค๋ฅธ ์„œ๋ฒ„ ๋˜๋Š” ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์„œ๋ฒ„๋Š” ์š”์ฒญ์— ์ „๋‹ฌ๋œ ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์–ด๋–ค ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ ์–ด๋–ค props๋ฅผ ์‚ฌ์šฉํ• ์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. + +์ด ์š”์ฒญ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ํŠน์ • URL์˜ ํŽ˜์ด์ง€ ์š”์ฒญ ํ˜•ํƒœ๋กœ ๋“ค์–ด์˜ค์ง€๋งŒ, Shopify Hydrogen์€ ๋” [์„ธ๋ถ„ํ™”๋œ ๋ฐฉ๋ฒ•](https://shopify.github.io/hydrogen-v1/tutorials/server-props)์„ ์ œ๊ณตํ•˜๋ฉฐ, React ํŒ€์˜ ๊ณต์‹ ๋ฐ๋ชจ์—๋Š” [์›์‹œ ๊ตฌํ˜„](https://github.com/reactjs/server-components-demo/blob/main/server/api.server.js)์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. + +## 2. ์„œ๋ฒ„๊ฐ€ ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ ์š”์†Œ๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”ํ•จ + +์—ฌ๊ธฐ์„œ ์ตœ์ข… ๋ชฉํ‘œ๋Š” ์ดˆ๊ธฐ ๋ฃจํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ธฐ๋ณธ HTML ํƒœ๊ทธ์™€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ "ํ”Œ๋ ˆ์ด์Šคํ™€๋”"์˜ ํŠธ๋ฆฌ๋กœ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด ํŠธ๋ฆฌ๋ฅผ ์ง๋ ฌํ™”ํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๋กœ ๋ณด๋‚ด๋ฉด, ๋ธŒ๋ผ์šฐ์ €๋Š” ์ด๋ฅผ ์—ญ์ง๋ ฌํ™”ํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ ํ”Œ๋ ˆ์ด์Šคํ™€๋”๋ฅผ ์‹ค์ œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ์ฑ„์›Œ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. + +๋”ฐ๋ผ์„œ, ์œ„์˜ ์˜ˆ๋ฅผ ๋”ฐ๋ฅด๋ฉด โ€” ``๋ฅผ ๋ Œ๋”๋งํ•˜๋ ค๊ณ  ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. + +์ง๋ ฌํ™”๋œ ์š”์†Œ ํŠธ๋ฆฌ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ๋‹จ์ˆœํžˆ JSON.stringify(``)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? + +๊ฑฐ์˜ ๋งž์ง€๋งŒ, ์™„์ „ํžˆ ๊ทธ๋ ‡์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค! ๐Ÿ˜… React ์š”์†Œ๊ฐ€ ์‹ค์ œ๋กœ ๋ฌด์—‡์ธ์ง€ ์ƒ๊ธฐํ•ด ๋ด…์‹œ๋‹ค โ€” React ์š”์†Œ๋Š” ๊ฐ์ฒด๋กœ, type ํ•„๋“œ๋Š” ๊ธฐ๋ณธ HTML ํƒœ๊ทธ๋ฅผ ์œ„ํ•œ ๋ฌธ์ž์—ด("div"์™€ ๊ฐ™์€) ๋˜๋Š” React ์ปดํฌ๋„ŒํŠธ ์ธ์Šคํ„ด์Šค๋ฅผ ์œ„ํ•œ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. + +```ts +// React element for
oh my
+> React.createElement("div", { title: "oh my" }) +{ + $$typeof: Symbol(react.element), + type: "div", + props: { title: "oh my" }, + ... +} + +// React element for oh my +> function MyComponent({children}) { + return
{children}
; + } +> React.createElement(MyComponent, { children: "oh my" }); +{ + $$typeof: Symbol(react.element), + type: MyComponent // reference to the MyComponent function + props: { children: "oh my" }, + ... +} +``` + +์šฐ๋ฆฌ๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ โ€œ๋ชจ๋“ˆ ์ฐธ์กฐโ€ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ด ์ž‘์—…์€ ์–ด๋””์„œ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? + +๊ฒฐ๊ตญ, ์ด ๋งˆ์ˆ ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์€ ๋ฒˆ๋“ค๋Ÿฌ์ž…๋‹ˆ๋‹ค! React ํŒ€์€ `react-server-dom-webpack`์—์„œ [webpack ๋กœ๋”](https://github.com/facebook/react/blob/main/packages/react-server-dom-webpack/src/ReactFlightWebpackNodeLoader.js) ๋˜๋Š” [node-register](https://github.com/facebook/react/blob/main/packages/react-server-dom-webpack/src/ReactFlightWebpackNodeRegister.js)๋กœ ๊ณต์‹ RSC ์ง€์›์„ ๋ฐœํ‘œํ–ˆ์Šต๋‹ˆ๋‹ค. + +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ \*.client.jsx ํŒŒ์ผ์—์„œ ๋ฌด์–ธ๊ฐ€๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์‹ค์ œ๋กœ ๊ทธ ํ•ญ๋ชฉ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋Œ€์‹  ํŒŒ์ผ ์ด๋ฆ„๊ณผ ๋‚ด๋ณด๋‚ธ ์ด๋ฆ„์„ ํฌํ•จํ•˜๋Š” ๋ชจ๋“ˆ ์ฐธ์กฐ ๊ฐ์ฒด๋งŒ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. + +ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋Š” ์„œ๋ฒ„์—์„œ ๊ตฌ์„ฑ๋œ React ํŠธ๋ฆฌ์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค! + +๋‹ค์‹œ ์œ„์˜ ์˜ˆ์ œ๋ฅผ ๊ณ ๋ คํ•ด๋ณด๋ฉด, ์šฐ๋ฆฌ๊ฐ€ ``๋ฅผ ์ง๋ ฌํ™”ํ•˜๋ ค๊ณ  ํ•  ๋•Œ, ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ JSON ํŠธ๋ฆฌ๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค: + +```ts +{ + // "๋ชจ๋“ˆ ์ฐธ์กฐ"๊ฐ€ ์žˆ๋Š” ClientComponent ์š”์†Œ ํ”Œ๋ ˆ์ด์Šคํ™€๋” + + type: { + $$typeof: Symbol(react.module.reference), + name: 'default', + filename: './src/ClientComponent.client.js', + }, + props: { + // ClientComponent์— ์ „๋‹ฌ๋œ ์ž์‹, ์ฆ‰ . + children: { + // ServerComponent๊ฐ€ ์ง์ ‘ html ํƒœ๊ทธ๋กœ ๋ Œ๋”๋ง๋จ; + // ServerComponent์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ์ „ํ˜€ ์—†์Œ์„ ์ฃผ๋ชฉํ•˜์„ธ์š”. + // ์šฐ๋ฆฌ๋Š” ์ง์ ‘ `span`์„ ๋ Œ๋”๋งํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + $$typeof: Symbol(react.element), + type: 'span', + props: { + children: 'Hello from server land', + }, + }, + }, +}; + +``` + +### ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ React ํŠธ๋ฆฌ + +์ด ๊ณผ์ •์ด ๋๋‚˜๋ฉด, ์„œ๋ฒ„์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ React ํŠธ๋ฆฌ๋ฅผ ์–ป๊ฒŒ ๋˜๊ณ , ์ด๋ฅผ ๋ธŒ๋ผ์šฐ์ €๋กœ ๋ณด๋‚ด "๋งˆ๋ฌด๋ฆฌ"๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค: + +![](https://www.plasmic.app/blog/static/images/react-server-components-placeholders.png) + +## ๋ชจ๋“  props๋Š” ์ง๋ ฌํ™”๊ฐ€ ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค + +์ „์ฒด React ํŠธ๋ฆฌ๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋‚˜ ๊ธฐ๋ณธ html ํƒœ๊ทธ์— ์ „๋‹ฌํ•˜๋Š” ๋ชจ๋“  props๋„ ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +์ด๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ prop์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค! + +```ts +// NOT OK: ํ•จ์ˆ˜๋Š” ์ง๋ ฌํ™” ๋  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„์ปดํฌ๋„ŒํŠธ๋Š” +// ์ž์‹์—๊ฒŒ ํ•จ์ˆ˜๋ฅผ props๋กœ ๋„˜๊ธธ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. +function SomeServerComponent() { + return ; +} +``` + +ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ•  ์ ์€ RSC ๊ณผ์ • ์ค‘์— ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋‚˜๋ฉด, ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€๋กœ ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +๋”ฐ๋ผ์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋˜ ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋Š” ๊ฒฝ์šฐ: + +```tsx +function SomeServerComponent() { + return Hello world!; +} + +function ClientComponent1({children}) { + // ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ props๋กœ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. + return {children}; +} +``` + +ClientComponent2๋Š” ์ด RSC JSON ํŠธ๋ฆฌ์— ์ „ํ˜€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +๋Œ€์‹ , ์šฐ๋ฆฌ๋Š” ClientComponent1์— ๋Œ€ํ•œ ๋ชจ๋“ˆ ์ฐธ์กฐ์™€ props๊ฐ€ ์žˆ๋Š” ์š”์†Œ๋งŒ ๋ณด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. + +๋”ฐ๋ผ์„œ ClientComponent1์ด ClientComponent2์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ prop์œผ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์ „ํ˜€ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. + +## 3. ๋ธŒ๋ผ์šฐ์ €์—์„œ React ํŠธ๋ฆฌ ์žฌ๊ตฌ์„ฑ + +๋ธŒ๋ผ์šฐ์ €๋Š” ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ JSON ์ถœ๋ ฅ์„ ๋ฐ›์•„, ์ด์ œ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ Œ๋”๋ง๋  React ํŠธ๋ฆฌ๋ฅผ ์žฌ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +`ํƒ€์ž…`์ด ๋ชจ๋“ˆ ์ฐธ์กฐ์ธ ์š”์†Œ๋ฅผ ๋งŒ๋‚  ๋•Œ๋งˆ๋‹ค, ์ด๋ฅผ ์‹ค์ œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜์˜ ์ฐธ์กฐ๋กœ ๊ต์ฒดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +์ด ์ž‘์—…์—๋Š” ๋ฒˆ๋“ค๋Ÿฌ์˜ ๋„์›€์ด ๋‹ค์‹œ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. + +๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ๋ชจ๋“ˆ ์ฐธ์กฐ๋กœ ๊ต์ฒดํ–ˆ์œผ๋ฉฐ, ์ด์ œ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ชจ๋“ˆ ์ฐธ์กฐ๋ฅผ ์‹ค์ œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋กœ ๊ต์ฒดํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•„๋Š” ๊ฒƒ๋„ ๋ฒˆ๋“ค๋Ÿฌ์ž…๋‹ˆ๋‹ค. + +์žฌ๊ตฌ์„ฑ๋œ React ํŠธ๋ฆฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค โ€” ๋„ค์ดํ‹ฐ๋ธŒ ํƒœ๊ทธ์™€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋งŒ ๊ต์ฒด๋œ ์ƒํƒœ๋กœ: + +![](https://www.plasmic.app/blog/static/images/react-server-components-client.png) + +๊ทธ๋Ÿฐ ๋‹ค์Œ ์šฐ๋ฆฌ๋Š” ์ด ํŠธ๋ฆฌ๋ฅผ ํ‰์†Œ์™€ ๊ฐ™์ด DOM์— ๋ Œ๋”๋งํ•˜๊ณ  ์ปค๋ฐ‹ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค! + +## ๊ทธ๋Ÿฐ๋ฐ ์ด๊ฒƒ์ด Suspense์™€ ํ•จ๊ป˜ ์ž‘๋™ํ• ๊นŒ์š”? + +๋„ค! Suspense๋Š” ์œ„์˜ ๋ชจ๋“  ๋‹จ๊ณ„์—์„œ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. + +์ด ๊ธ€์—์„œ๋Š” Suspense์— ๋Œ€ํ•ด ์˜๋„์ ์œผ๋กœ ์ž์„ธํžˆ ๋‹ค๋ฃจ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. + +Suspense ์ž์ฒด๊ฐ€ ๋งค์šฐ ํฐ ์ฃผ์ œ์ด๋ฉฐ, ๋ณ„๋„์˜ ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. + +ํ•˜์ง€๋งŒ ๊ฐ„๋‹จํžˆ ๋งํ•˜์ž๋ฉด โ€” Suspense๋Š” React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•„์ง ์ค€๋น„๋˜์ง€ ์•Š์€ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•„์š”๋กœ ํ•  ๋•Œ(๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜, ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ง€์—ฐ ๋กœ๋“œํ•˜๋Š” ๋“ฑ) Promise๋ฅผ ๋˜์งˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. + +์ด๋Ÿฌํ•œ Promise๋Š” "Suspense ๊ฒฝ๊ณ„"์—์„œ ์žกํžˆ๋ฉฐ โ€” Suspense ํ•˜์œ„ ํŠธ๋ฆฌ์˜ ๋ Œ๋”๋ง์—์„œ Promise๊ฐ€ ๋˜์ ธ์ง€๋ฉด, React๋Š” ํ•ด๋‹น Promise๊ฐ€ ํ•ด๊ฒฐ๋  ๋•Œ๊นŒ์ง€ ํ•ด๋‹น ํ•˜์œ„ ํŠธ๋ฆฌ์˜ ๋ Œ๋”๋ง์„ ์ค‘์ง€ํ•˜๊ณ , ์ดํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. + +์„œ๋ฒ„์—์„œ RSC ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ํ•ด๋‹น ํ•จ์ˆ˜๋“ค์ด ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋ฉด์„œ Promise๋ฅผ ๋˜์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด๋Ÿฌํ•œ [Promise๋ฅผ ๋งŒ๋‚ฌ์„ ๋•Œ](https://github.com/facebook/react/blob/42c30e8b122841d7fe72e28e36848a6de1363b0c/packages/react-server/src/ReactFlightServer.js#L416)๋Š” ํ”Œ๋ ˆ์ด์Šคํ™€๋”๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. + +Promise๊ฐ€ ํ•ด๊ฒฐ๋˜๋ฉด ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜์—ฌ ์™„๋ฃŒ๋œ ์ฒญํฌ๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. + +์šฐ๋ฆฌ๋Š” ์‹ค์ œ๋กœ RSC ์ถœ๋ ฅ์˜ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, Promise๊ฐ€ ๋˜์ ธ์งˆ ๋•Œ ๋ฉˆ์ถ”๊ณ , ํ•ด๊ฒฐ๋˜๋ฉด ์ถ”๊ฐ€ ์ฒญํฌ๋ฅผ ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค. + +๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๋ธŒ๋ผ์šฐ์ €์—์„œ๋„ ์œ„์˜ `fetch()` ํ˜ธ์ถœ๋กœ๋ถ€ํ„ฐ RSC JSON ์ถœ๋ ฅ์„ ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค. + +์ด ๊ณผ์ •์—์„œ๋„ ์ถœ๋ ฅ์—์„œ ์„œ์ŠคํŽœ์Šค ํ”Œ๋ ˆ์ด์Šคํ™€๋”(์„œ๋ฒ„์—์„œ Promise๊ฐ€ ๋˜์ ธ์ง„ ๋ถ€๋ถ„)๋ฅผ ๋งŒ๋‚˜๊ณ , ์•„์ง ์ŠคํŠธ๋ฆผ์—์„œ ํ•ด๋‹น ํ”Œ๋ ˆ์ด์Šคํ™€๋” ๋‚ด์šฉ์„ ๋ณด์ง€ ๋ชปํ•œ ๊ฒฝ์šฐ Promise๋ฅผ ๋˜์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์—ฌ๊ธฐ์—๋Š” ์•ฝ๊ฐ„์˜ [์„ธ๋ถ€ ์‚ฌํ•ญ](https://github.com/facebook/react/blob/main/packages/react-client/src/ReactFlightClientStream.js)์ด ์žˆ์Šต๋‹ˆ๋‹ค). + +๋˜ํ•œ, ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ๋ชจ๋“ˆ ์ฐธ์กฐ๋ฅผ ๋งŒ๋‚˜์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ €์— ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๊ฐ€ ์•„์ง ๋กœ๋“œ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋„ Promise๋ฅผ ๋˜์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด ๊ฒฝ์šฐ ๋ฒˆ๋“ค๋Ÿฌ ๋Ÿฐํƒ€์ž„์ด ํ•„์š”ํ•œ [์ฒญํฌ๋ฅผ ๋™์ ์œผ๋กœ ๊ฐ€์ ธ์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค.](https://github.com/facebook/react/blob/main/packages/react-server-dom-webpack/src/ReactFlightClientWebpackBundlerConfig.js) + +Suspense ๋•๋ถ„์— ์„œ๋ฒ„๋Š” ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋™์•ˆ RSC ์ถœ๋ ฅ์„ ์ŠคํŠธ๋ฆฌ๋ฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์งˆ ๋•Œ๋งˆ๋‹ค ์ ์ง„์ ์œผ๋กœ ๋ Œ๋”๋งํ•˜๊ณ , ํ•„์š”์— ๋”ฐ๋ผ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ๋ฒˆ๋“ค์„ ๋™์ ์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +# RSC ์™€์ด์–ด ํฌ๋งท + +ํ•˜์ง€๋งŒ ์„œ๋ฒ„๊ฐ€ ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ผ๊นŒ์š”? "JSON"๊ณผ "์ŠคํŠธ๋ฆผ"์ด๋ผ๋Š” ๋‹จ์–ด๋ฅผ ์ฝ๊ณ  ์˜์•„ํ•˜๊ฒŒ ์—ฌ๊ฒผ๋‹ค๋ฉด, ๋„ˆ๋ฌด ๋‹น์—ฐํ•ฉ๋‹ˆ๋‹ค! + +๊ทธ๋ ‡๋‹ค๋ฉด ์„œ๋ฒ„๊ฐ€ ๋ธŒ๋ผ์šฐ์ €๋กœ ์ŠคํŠธ๋ฆฌ๋ฐํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋ฌด์—‡์ผ๊นŒ์š”? + +์ด๊ฒƒ์€ ๊ฐ„๋‹จํ•œ ํฌ๋งท์œผ๋กœ, ๊ฐ ์ค„์— ID๊ฐ€ ํƒœ๊ทธ๋œ ํ•˜๋‚˜์˜ JSON ๋ธ”๋กญ์ด ์žˆ์Šต๋‹ˆ๋‹ค. + +๋‹ค์Œ์€ ์˜ˆ์ œ์˜ RSC ์ถœ๋ ฅ์ž…๋‹ˆ๋‹ค: + +``` +M1:{"id":"./src/ClientComponent.client.js","chunks":["client1"],"name":""} +J0:["$","@1",null,{"children":["$","span",null,{"children":"Hello from server land"}]}] +``` + +์œ„์˜ ์ฝ”๋“œ ์กฐ๊ฐ์—์„œ `M`์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ค„์€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ๋ชจ๋“ˆ ์ฐธ์กฐ๋ฅผ ์ •์˜ํ•˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ ๋ฒˆ๋“ค์—์„œ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ ์ฐพ๋Š” ๋ฐ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. + +`J`๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ค„์€ ์‹ค์ œ React ์š”์†Œ ํŠธ๋ฆฌ๋ฅผ ์ •์˜ํ•˜๋ฉฐ, `@1`๊ณผ ๊ฐ™์€ ์ฐธ์กฐ๋Š” `M` ์ค„์—์„œ ์ •์˜๋œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. + +์ด ํฌ๋งท์€ ๋งค์šฐ ์ŠคํŠธ๋ฆฌ๋ฐ ๊ฐ€๋Šฅํ•˜์—ฌ, ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ „์ฒด ํ–‰์„ ์ฝ๋Š” ์ฆ‰์‹œ JSON ์กฐ๊ฐ์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๊ณ  ์ผ๋ถ€ ์ž‘์—…์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์„œ๋ฒ„๊ฐ€ ๋ Œ๋”๋ง ์ค‘์— ์„œ์ŠคํŽœ์Šค ๊ฒฝ๊ณ„๋ฅผ ๋งŒ๋‚ฌ๋‹ค๋ฉด, ๊ฐ ์ฒญํฌ๊ฐ€ ํ•ด๊ฒฐ๋  ๋•Œ๋งˆ๋‹ค ์—ฌ๋Ÿฌ `J` ์ค„์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์˜ˆ๋ฅผ ๋“ค์–ด์„œ, ๋”์šฑ ๊ตฌ์ฒด์ ์ธ ์˜ˆ๋ฅผ ํ•˜๋‚˜ ๋” ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. + +```tsx +// Tweets.server.js +import { fetch } from "react-fetch"; // React's Suspense-aware fetch() +import Tweet from "./Tweet.client"; +export default function Tweets() { + const tweets = fetch(`/tweets`).json(); + return ( +
    + {tweets.slice(0, 2).map((tweet) => ( +
  • + +
  • + ))} +
+ ); +} + +// Tweet.client.js +export default function Tweet({ tweet }) { + return ( +
alert(`Written by ${tweet.username}`)}> + {tweet.body} +
+ ); +} + +// OuterServerComponent.server.js +export default function OuterServerComponent() { + return ( + + + + + + + ); +} +``` + +์ด ๊ฒฝ์šฐ์—์„  RSC ์ŠคํŠธ๋ฆผ์ด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”? + +``` +M1:{"id":"./src/ClientComponent.client.js","chunks":["client1"],"name":""} +S2:"react.suspense" + +J0:["$","@1",null,{"children":[["$","span",null,{"children":"Hello from server land"}],["$","$2",null,{"fallback":"Loading tweets...","children":"@3"}]]}] + +M4:{"id":"./src/Tweet.client.js","chunks":["client8"],"name":""} + +J3:["$","ul",null,{"children":[["$","li",null,{"children":["$","@4",null,{"tweet":{...}}}]}],["$","li",null,{"children":["$","@4",null,{"tweet":{...}}}]}]]}] +``` + +`J0` ์ค„์—๋Š” ์ด์ œ ์ถ”๊ฐ€ ์ž์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค โ€” ์ƒˆ๋กœ์šด `Suspense` ๊ฒฝ๊ณ„๋กœ, `children`์ด ์ฐธ์กฐ @3์„ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + +์—ฌ๊ธฐ์„œ ํฅ๋ฏธ๋กœ์šด ์ ์€ `@3`์ด ์ด ์‹œ์ ์—์„œ๋Š” ์•„์ง ์ •์˜๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค! + +์„œ๋ฒ„๊ฐ€ ํŠธ์œ—์„ ๋กœ๋“œํ•˜๋Š” ์ž‘์—…์„ ์™„๋ฃŒํ•˜๋ฉด, `M4` ์ค„์„ ์ถœ๋ ฅํ•˜์—ฌ `Tweet.client.js` ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•œ ๋ชจ๋“ˆ ์ฐธ์กฐ๋ฅผ ์ •์˜ํ•˜๊ณ , `J3` ์ค„์„ ์ถœ๋ ฅํ•˜์—ฌ` @3`์ด ์žˆ๋Š” ์œ„์น˜์— ๊ต์ฒด๋  ๋˜ ๋‹ค๋ฅธ React ์š”์†Œ ํŠธ๋ฆฌ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. +(๋˜ํ•œ `J3`์˜ ์ž์‹์ด `M4`์—์„œ ์ •์˜๋œ `Tweet` ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•˜์„ธ์š”). + +์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ•  ๋˜ ๋‹ค๋ฅธ ์ ์€, ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ `ClientComponent`์™€ `Tweet`์„ ์ž๋™์œผ๋กœ ๋‘ ๊ฐœ์˜ ๋ณ„๋„ ๋ฒˆ๋“ค๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ `Tweet` ๋ฒˆ๋“ค์„ ๋‚˜์ค‘์— ๋‹ค์šด๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค! + +## RSC ํฌ๋งท ์†Œ๋น„ํ•˜๊ธฐ + +์ด RSC ์ŠคํŠธ๋ฆผ์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹ค์ œ React ์š”์†Œ๋กœ ์–ด๋–ป๊ฒŒ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? `react-server-dom-webpack`์—๋Š” RSC ์‘๋‹ต์„ ๋ฐ›์•„์„œ React ์š”์†Œ ํŠธ๋ฆฌ๋ฅผ ์žฌ์ƒ์„ฑํ•˜๋Š” [์ง„์ž…์ ](https://github.com/facebook/react/blob/main/packages/react-server-dom-webpack/src/ReactFlightDOMClient.js)์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. + +๋‹ค์Œ์€ ๋ฃจํŠธ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์˜ ๋‹จ์ˆœํ™”๋œ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค: + +```ts +import { createFromFetch } from 'react-server-dom-webpack' +function ClientRootComponent() { + // ์šฐ๋ฆฌ์˜ RSC API ์—”๋“œํฌ์ธํŠธ์—์„œ fetch()๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. react-server-dom-webpack์€ + // fetch ๊ฒฐ๊ณผ๋ฅผ ๋ฐ›์•„์„œ React ์š”์†Œ ํŠธ๋ฆฌ๋ฅผ ์žฌ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + const response = createFromFetch(fetch('/rsc?...')) + return {response.readRoot() /* React ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค! */} +} +``` + +`react-server-dom-webpack`์—๊ฒŒ API ์—”๋“œํฌ์ธํŠธ์—์„œ RSC ์‘๋‹ต์„ ์ฝ๋„๋ก ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฐ ๋‹ค์Œ, `response.readRoot()`๋Š” ์‘๋‹ต ์ŠคํŠธ๋ฆผ์ด ์ฒ˜๋ฆฌ๋จ์— ๋”ฐ๋ผ ์—…๋ฐ์ดํŠธ๋˜๋Š” React ์š”์†Œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค! + +์ŠคํŠธ๋ฆผ์ด ์ „ํ˜€ ์ฝํžˆ์ง€ ์•Š์€ ์ƒํƒœ์—์„œ๋Š” ๋‚ด์šฉ์ด ์ค€๋น„๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฆ‰์‹œ Promise๋ฅผ ๋˜์ง‘๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฐ ๋‹ค์Œ ์ฒซ ๋ฒˆ์งธ `J0`๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉด์„œ ํ•ด๋‹นํ•˜๋Š” React ์š”์†Œ ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋˜์ ธ์ง„ Promise๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. + +React๋Š” ๋ Œ๋”๋ง์„ ์žฌ๊ฐœํ•˜์ง€๋งŒ ์•„์ง ์ค€๋น„๋˜์ง€ ์•Š์€ `@3` ์ฐธ์กฐ๋ฅผ ๋งŒ๋‚˜๋ฉด ๋˜ ๋‹ค๋ฅธ Promise๊ฐ€ ๋˜์ ธ์ง‘๋‹ˆ๋‹ค. + +๊ทธ๋ฆฌ๊ณ  `J3`์„ ์ฝ์œผ๋ฉด ๊ทธ Promise๊ฐ€ ํ•ด๊ฒฐ๋˜๊ณ , React๋Š” ๋‹ค์‹œ ๋ Œ๋”๋ง์„ ์žฌ๊ฐœํ•˜์—ฌ ์ด๋ฒˆ์—๋Š” ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค. + +๋”ฐ๋ผ์„œ RSC ์‘๋‹ต์„ ์ŠคํŠธ๋ฆฌ๋ฐํ•˜๋Š” ๋™์•ˆ ์šฐ๋ฆฌ๋Š” Suspense ๊ฒฝ๊ณ„๋กœ ์ •์˜๋œ ์ฒญํฌ์—์„œ ์š”์†Œ ํŠธ๋ฆฌ๋ฅผ ๊ณ„์† ์—…๋ฐ์ดํŠธํ•˜๊ณ  ๋ Œ๋”๋งํ•˜๊ฒŒ ๋˜๋ฉฐ, ๋๋‚  ๋•Œ๊นŒ์ง€ ์ด ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. + +## ์™œ ๋‹จ์ˆœํžˆ HTML์„ ์ถœ๋ ฅํ•˜์ง€ ์•Š์„๊นŒ์š”? + +์™œ ์ƒˆ๋กœ์šด ์™€์ด์–ด ํฌ๋งท์„ ๋ฐœ๋ช…ํ–ˆ์„๊นŒ์š”? ํด๋ผ์ด์–ธํŠธ์˜ ๋ชฉํ‘œ๋Š” React ์š”์†Œ ํŠธ๋ฆฌ๋ฅผ ์žฌ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +HTML์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜์—ฌ React ์š”์†Œ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋ณด๋‹ค ์ด ํฌ๋งท์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค. + +React ์š”์†Œ ํŠธ๋ฆฌ๋ฅผ ์žฌ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•œ ์ด์œ ๋Š”, ์ด๋ฅผ ํ†ตํ•ด React ํŠธ๋ฆฌ์— ๋Œ€ํ•œ ํ›„์† ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ตœ์†Œํ•œ์˜ DOM ์ปค๋ฐ‹์œผ๋กœ ๋ณ‘ํ•ฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. + +## ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ๋ณด๋‹ค ์ด๊ฒƒ์ด ๋” ๋‚˜์€๊ฐ€์š”? + +์–ด์ฐจํ”ผ ์ด ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„์— API ์š”์ฒญ์„ ํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ์˜ค๋Š˜๋‚ ์ฒ˜๋Ÿผ ๋‹จ์ˆœํžˆ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€์„œ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ Œ๋”๋ง์„ ์™„์ „ํžˆ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์ด ๋ฐฉ๋ฒ•์ด ์ •๋ง ๋” ๋‚˜์€๊ฐ€์š”? + +๊ถ๊ทน์ ์œผ๋กœ, ํ™”๋ฉด์— ๋ฌด์—‡์„ ๋ Œ๋”๋งํ•˜๋Š๋ƒ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. + +RSC๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ค„ ๋‚ด์šฉ์— ์ง์ ‘์ ์œผ๋กœ ๋งคํ•‘๋˜๋Š” ๋น„์ •๊ทœํ™”๋œ "์ฒ˜๋ฆฌ๋œ" ๋ฐ์ดํ„ฐ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ๊ฐ€์ ธ์˜ฌ ๋ฐ์ดํ„ฐ์˜ ์ž‘์€ ๋ถ€๋ถ„๋งŒ ๋ Œ๋”๋งํ•˜๊ฑฐ๋‚˜ ๋ Œ๋”๋ง ์ž์ฒด์— ๋งŽ์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํ•„์š”ํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๋กœ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. + +๋˜ํ•œ ๋ Œ๋”๋ง์ด ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ํ•„์š”๋กœ ํ•˜๊ณ , ์ด ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ๊ณ„๋‹จ์‹์œผ๋กœ ์„œ๋กœ ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ ์ง€์—ฐ์ด ํ›จ์”ฌ ๋‚ฎ์€ ์„œ๋ฒ„์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ์ข‹์Šต๋‹ˆ๋‹ค. + +## ํ•˜์ง€๋งŒโ€ฆ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์€์š”? + +์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. + +React 18์„ ์‚ฌ์šฉํ•˜๋ฉด SSR๊ณผ RSC๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ์„œ๋ฒ„์—์„œ HTML์„ ์ƒ์„ฑํ•˜๊ณ , ๋ธŒ๋ผ์šฐ์ €์—์„œ RSC๋กœ ๊ทธ HTML์„ ํ•˜์ด๋“œ๋ ˆ์ด์…˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด ์ฃผ์ œ์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ๊ธฐ๋Œ€ํ•ด์ฃผ์„ธ์š”! + +## ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋งํ•˜๋Š” ๋‚ด์šฉ์„ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ + +์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒˆ๋กœ์šด ๋‚ด์šฉ์„ ๋ Œ๋”๋งํ•ด์•ผ ํ•œ๋‹ค๋ฉด โ€” ์˜ˆ๋ฅผ ๋“ค์–ด, ํ•œ ์ œํ’ˆ ํŽ˜์ด์ง€์—์„œ ๋‹ค๋ฅธ ์ œํ’ˆ ํŽ˜์ด์ง€๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด๋ณด์„ธ์š”. + +๋‹ค์‹œ ๋งํ•ด, ๋ Œ๋”๋ง์ด ์„œ๋ฒ„์—์„œ ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒˆ๋กœ์šด RSC ์™€์ด์–ด ํฌ๋งท์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„์— ๋˜ ๋‹ค๋ฅธ API ํ˜ธ์ถœ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. + +์ข‹์€ ์†Œ์‹์€, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ƒˆ๋กœ์šด ์ฝ˜ํ…์ธ ๋ฅผ ๋ฐ›์œผ๋ฉด ์ƒˆ๋กœ์šด React ์š”์†Œ ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ , ์ด์ „ React ํŠธ๋ฆฌ์™€์˜ ์ฐจ์ด๋ฅผ ๋น„๊ตํ•˜์—ฌ DOM์— ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +์ด ๊ณผ์ •์—์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ์™€ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ๊ทธ๋Œ€๋กœ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. + +ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ์ž…์žฅ์—์„œ๋Š” ์ด ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ธŒ๋ผ์šฐ์ € ๋‚ด์—์„œ ์ „์ ์œผ๋กœ ๋ฐœ์ƒํ•œ ๊ฒƒ๊ณผ ๋‹ค๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. + +ํ˜„์žฌ๋Š” ๋ฃจํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ถ€ํ„ฐ ์ „์ฒด React ํŠธ๋ฆฌ๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ด์•ผ ํ•˜์ง€๋งŒ, ๋ฏธ๋ž˜์—๋Š” ์„œ๋ธŒ ํŠธ๋ฆฌ์— ๋Œ€ํ•ด์„œ๋„ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +## RSC์— ๋ฉ”ํƒ€ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”? + +React ํŒ€์€ RSC๊ฐ€ ์ฒ˜์Œ์—๋Š” Next.js๋‚˜ Shopify Hydrogen ๊ฐ™์€ [๋ฉ”ํƒ€ ํ”„๋ ˆ์ž„์›Œํฌ](https://github.com/josephsavona/rfcs/blob/server-components/text/0000-server-components.md#adoption-strategy)๋ฅผ ํ†ตํ•ด ๋„์ž…๋˜๋„๋ก ์˜๋„ํ–ˆ๋‹ค๊ณ  ๋งํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์™œ ๊ทธ๋Ÿด๊นŒ์š”? ๋ฉ”ํƒ€ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์–ด๋–ค ๋„์›€์„ ์ฃผ๋‚˜์š”? + +๊ผญ ์‚ฌ์šฉํ•  ํ•„์š”๋Š” ์—†์ง€๋งŒ, ์‚ฌ์šฉํ•˜๋ฉด ํ›จ์”ฌ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. + +๋ฉ”ํƒ€ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์นœ์ˆ™ํ•œ ๋ž˜ํผ(Wrapper)์™€ ์ถ”์ƒํ™”๋ฅผ ์ œ๊ณตํ•˜์—ฌ ์„œ๋ฒ„์—์„œ RSC ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ด๋ฅผ ์†Œ๋น„ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์‹ ๊ฒฝ ์“ธ ํ•„์š”๊ฐ€ ์—†๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค. + +๋ฉ”ํƒ€ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง๋„ ์ง€์›ํ•˜๋ฉฐ, ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ HTML์„ ์ œ๋Œ€๋กœ ํ•˜์ด๋“œ๋ ˆ์ด์…˜ํ•  ์ˆ˜ ์žˆ๋„๋ก [์ž‘์—…](https://github.com/vercel/next.js/issues/30994)์„ [์ˆ˜ํ–‰](https://github.com/Shopify/hydrogen/pull/250)ํ•ฉ๋‹ˆ๋‹ค. + +๋ณด์…จ๋‹ค์‹œํ”ผ, ๋ธŒ๋ผ์šฐ์ €์—์„œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ œ๊ณตํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์—๋Š” ๋ฒˆ๋“ค๋Ÿฌ์˜ ํ˜‘๋ ฅ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. + +์ด๋ฏธ webpack ํ†ตํ•ฉ์ด ์žˆ์œผ๋ฉฐ, Shopify๋Š” [vite ํ†ตํ•ฉ ์ž‘์—…](https://github.com/facebook/react/pull/22952)์„ ์ง„ํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค. + +์ด๋Ÿฌํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ RSC์— ํ•„์š”ํ•œ ๋งŽ์€ ๋ถ€๋ถ„์ด ๊ณต๊ฐœ npm ํŒจํ‚ค์ง€๋กœ ๊ฒŒ์‹œ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— React ์ €์žฅ์†Œ์˜ ์ผ๋ถ€๊ฐ€ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +๊ทธ๋Ÿฌ๋‚˜ ๊ฐœ๋ฐœ์ด ์™„๋ฃŒ๋˜๋ฉด, ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋ฉ”ํƒ€ ํ”„๋ ˆ์ž„์›Œํฌ ์—†์ด๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. + +## RSC๊ฐ€ ์ค€๋น„๋˜์—ˆ๋‚˜์š”? + +๋ฆฌ์•กํŠธ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ํ˜„์žฌ [Next.js์˜ ์‹คํ—˜์  ๊ธฐ๋Šฅ](https://nextjs.org/docs/app/building-your-application/rendering/server-components)๊ณผ [Shopify Hydrogen์˜](https://hydrogen.shopify.dev/) ํ˜„์žฌ ๊ฐœ๋ฐœ์ž ํ”„๋ฆฌ๋ทฐ๋กœ ์ œ๊ณต๋˜๊ณ  ์žˆ์ง€๋งŒ, ์–ด๋Š ๊ฒƒ๋„ ์•„์ง ํ”„๋กœ๋•์…˜์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ์—๋Š” ์ค€๋น„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. + +์•ž์œผ๋กœ์˜ ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ์—์„œ ๊ฐ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ RSC๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์ž์„ธํžˆ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. + +ํ•˜์ง€๋งŒ React Server Components๊ฐ€ React์˜ ๋ฏธ๋ž˜์— ํฐ ๋ถ€๋ถ„์„ ์ฐจ์ง€ํ•  ๊ฒƒ์ด๋ผ๋Š” ์ ์€ ํ™•์‹คํ•ฉ๋‹ˆ๋‹ค. + +์ด๋Š” ๋” ๋น ๋ฅธ ํŽ˜์ด์ง€ ๋กœ๋“œ, ๋” ์ž‘์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฒˆ๋“ค, ๊ทธ๋ฆฌ๊ณ  ๋” ์งง์€ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์‹œ๊ฐ„์— ๋Œ€ํ•œ React์˜ ํ•ด๋‹ต์ž…๋‹ˆ๋‹ค โ€” React๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ€ํ‹ฐ ํŽ˜์ด์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋” ํฌ๊ด„์ ์ธ ๋…ผ์ œ์ž…๋‹ˆ๋‹ค. + +์•„์ง ์ค€๋น„๋˜์ง€ ์•Š์•˜์ง€๋งŒ, ๊ณง ์ฃผ๋ชฉํ•  ์‹œ๊ธฐ๊ฐ€ ์˜ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค. + +## Plasmic์˜ React Server Components ์‚ฌ์šฉ + +Plasmic์€ ์ฝ˜ํ…์ธ  ์ œ์ž‘์ž๊ฐ€ ๋žœ๋”ฉ ํŽ˜์ด์ง€ ๋ฐ ๊ณ ์„ฑ๋Šฅ React ์›น์‚ฌ์ดํŠธ์™€ ์Šคํ† ์–ดํ”„๋ก ํŠธ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋ฉฐ, ๊ฐœ๋ฐœ์ž๋Š” ์ฝ˜ํ…์ธ  ํŽ˜์ด์ง€ ์ž‘์—…์—์„œ ์ž์œ ๋กœ์›Œ์ง€๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. + +Plasmic์€ ๊ธฐ์กด React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์บ”๋ฒ„์Šค์— ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญํ•  ์ˆ˜ ์žˆ๋„๋ก ๊นŠ์ด ์žˆ๋Š” React ์ง€์›์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. + +React Server Components์™€ ๊ฐ™์€ ์„ฑ๋Šฅ ํ–ฅ์ƒ ๋„๊ตฌ๋Š” ์šฐ๋ฆฌ์™€ ๊ณ ๊ฐ ๋ชจ๋‘์—๊ฒŒ ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. + +๋„์ „์ ์ธ ์‚ฌ์šฉ์ž๋“ค์„ ์œ„ํ•ด: [์ด์ œ Shopify Hydrogen๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š” Plasmic ๋ฐ๋ชจ](https://github.com/plasmicapp/hydrogen-demo)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. + +์ด๋Š” Shopify Hydrogen ์›น์‚ฌ์ดํŠธ ๋‚ด์—์„œ ์‹œ๊ฐ์ ์œผ๋กœ ํŽ˜์ด์ง€๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ , ํŽธ์ง‘๊ธฐ์—์„œ ๊ธฐ์กด React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญํ•  ์ˆ˜ ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. + +๋˜๋Š” [Plasmic](https://studio.plasmic.app/)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž์‹ ์˜ ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ์‹œ๊ฐ์ ์œผ๋กœ ๊ตฌ์ถ•์„ ์‹œ์ž‘ํ•ด๋ณด์„ธ์š”! + +์ด ๊ธ€์˜ ์ดˆ๊ธฐ ์ดˆ์•ˆ์„ ๊ฒ€ํ† ํ•ด์ฃผ์‹  Hassan๊ณผ Josh์—๊ฒŒ ๋งŽ์€ ๊ฐ์‚ฌ๋ฅผ ๋“œ๋ฆฝ๋‹ˆ๋‹ค!