React: [์šฐ์‚ฐ] ์„œ์ŠคํŽœ์Šค๋ฅผ ํ’€์–ด

์— ๋งŒ๋“  2018๋…„ 07์›” 13์ผ  ยท  83์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: facebook/react

์ด ๋ฌธ์ œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Suspense๋ฅผ ์˜คํ”ˆ ์†Œ์Šค๋กœ ๋ฆด๋ฆฌ์Šคํ•˜๊ธฐ ์œ„ํ•œ ๋‚˜๋จธ์ง€ ์ž‘์—…์„ ์ถ”์ ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ดˆ๊ธฐ ๋ฆด๋ฆฌ์Šค(MVP)

ํ•ต์‹ฌ

  • [x] ๋ Œ๋”๋ง ๋‹จ๊ณ„ ํ•จ์ˆ˜(@acdlite) ๋‚ด์—์„œ ์ปจํ…์ŠคํŠธ๋ฅผ ์ฝ๋Š” API [#13139]
  • [x] ์‹œ๊ฐ„ ์ดˆ๊ณผ ์ฝ˜ํ…์ธ ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๋Œ€์‹  ์ˆจ๊ธฐ๊ธฐ(@acdlite) [#13120]
  • [ ] React ๋ฃจํŠธ(@acdlite)๋‹น ์ปจํ…์ŠคํŠธ ์ œ๊ณต์ž ์ž๋™ ์ฃผ์ž… [#13293]
  • [ ] AsyncMode ์—์„œ unstable_ ์ ‘๋‘์‚ฌ ์ œ๊ฑฐ(์•„๋งˆ๋„?)
  • [ ] ๋™๊ธฐ์‹ thenable ๋ฐ ๋ Œ๋”๋ง ๋‹จ๊ณ„๊ฐ€ ์™„๋ฃŒ๋˜๊ธฐ ์ „์— ํ•ด๊ฒฐ๋˜๋Š” ์•ฝ์†์— ๋Œ€ํ•œ ์ง€์›.

    • [ ] ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๋™๊ธฐ์‹ thenable์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋Š”์ง€ ํ™•์ธ

  • [ ] <div hidden> ์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธ [#13089]
  • [ ] ์กฐ๋ช…๊ธฐ์—์„œ ์—ฌ๋Ÿฌ ์„ธ๋ถ€ ๋งํฌ๋ฅผ ํ•˜๋‚˜์”ฉ ํด๋ฆญํ•˜๋ฉด ๋‹ค์Œ ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๊ธฐ ์ „์— ๊ฐ ๋งํฌ๋ฅผ ํ”Œ๋ ˆ์ด์Šคํ™€๋” ์ง€์—ฐ ์‹œ๊ฐ„๋ณด๋‹ค ์ ๊ฒŒ ๊ธฐ๋‹ค๋ฆฌ๋”๋ผ๋„ ๊ฒฐ๊ตญ ํฐ ํ”Œ๋ ˆ์ด์Šคํ™€๋”๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ( ํŠธ์œ— ์ฐธ์กฐ )?

๋‹จ์ˆœ ์บ์‹œ ๊ณต๊ธ‰์ž

  • [ ] ์บ์‹œ ๋ฌดํšจํ™”(@acdlite) [#13337]
  • [ ] ๊ตฌ๋…(@acdlite) [#13337]
  • [ ] ์‹ค๋ช…์œผ๋กœ ๊ฒฐ์ •

์ฝ”๋“œ ๋ถ„ํ• 

  • [x] ์ปดํฌ๋„ŒํŠธ ์œ ํ˜•์œผ๋กœ Promise ์ง€์›
  • [x] (์•„๋งˆ๋„) ์˜คํ”ˆ ์†Œ์Šค lazyLoadComponent ?

ํ…Œ์ŠคํŠธ ๋ Œ๋”๋Ÿฌ

  • [ ] flushAll , yield ๋“ฑ์— ๋Œ€ํ•œ ๊ณต๊ฐœ API ๋งˆ๋ฌด๋ฆฌ

    • ์ž ์ •์ ์ธ ๊ณ„ํš์€ #13236์˜ ์ฃผ์š” ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐ๊ฐ์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ์ง€์ • ๋งค์ฒ˜๋ฅผ ๊ฒŒ์‹œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฌธ์„œ

  • [ ] ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ
  • [ ] React.Placeholder
  • [ ] ๋‹จ์ˆœ ์บ์‹œ ๊ณต๊ธ‰์ž
  • [ ] ์ด๋ฆ„ ์—†๋Š” ์ฝ”๋“œ ๋ถ„ํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

ํ›„์† ์กฐ์น˜

์†Œํ”„ํŠธ ๋งŒ๋ฃŒ(https://github.com/facebook/react/issues/14248)

  • [ ] ์ƒ์œ„ ํ•ญ๋ชฉ์ด ์•„๋‹Œ ์ธํ”Œ๋ ˆ์ด์Šค ๋กœ๋”ฉ ์ธ๋””์ผ€์ดํ„ฐ์šฉ API ๊ตฌํ˜„
  • [ ] ์ธ๋ผ์ธ ์Šคํ”ผ๋„ˆ๊ฐ€ ์ถฉ๋ถ„ํžˆ ๋น ๋ฅธ ๊ฒฝ์šฐ ๊นœ๋ฐ•์ด์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ

  • [ ] @acdlite ์˜ ZEIT ํ† ํฌ์— ์žˆ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • [ ] ๋ถ€๋ถ„์ˆ˜ํ™”

๊ด€๋ จ: ํƒ€์ž„ ์Šฌ๋ผ์ด์‹ฑ ์šฐ์‚ฐ (https://github.com/facebook/react/issues/13306)

React Core Team Umbrella

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@mschipperheyn

์ด๊ฒƒ์€ ๋‹ค๋…„๊ฐ„์˜ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์ •์งํ•œ ๋Œ€๋‹ต์€ ์šฐ๋ฆฌ๊ฐ€ 2๋…„ ์ „์— ์‹œ์ž‘ํ–ˆ์„ ๋•Œ ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋งŽ์€ ์ž‘์—…์„ ๋‚ณ์•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ข‹์€ ์†Œ์‹์€ ์ด์ œ ํ”„๋กœ๋•์…˜์—์„œ ๋งŽ์ด ์‚ฌ์šฉ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ˆ„๋ฝ๋œ ๋ถ€๋ถ„์ด ๋ช…ํ™•ํ•˜๊ณ  ํ„ฐ๋„์˜ ๋์ด ๋ณด์ž…๋‹ˆ๋‹ค. ์ด๋ก ์ ์ธ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์ฑ„ํƒํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ํŽธ์•ˆํ•˜๊ฒŒ ๋งํ•  ์ˆ˜ ์žˆ๊ธฐ ์ „์— ์™„๋ฃŒํ•ด์•ผ ํ•˜๋Š” ์œ ํ•œํ•œ ์„ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜๋‚  ๋‹ค์–‘ํ•œ ์ž‘์—… ํ๋ฆ„์˜ ๋Œ€๋žต์ ์ธ ์ƒํƒœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • <Suspense> ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ ๋ถ„ํ• ์— ๋Œ€ํ•œ API lazy . (16.6 ๋ฐ˜์‘์— ์ œ๊ณต)

    • ์•„์‹œ๋‹ค์‹œํ”ผ ์ด๋ฏธ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋™์‹œ ๋ชจ๋“œ API, ์˜ˆ: createRoot ๋ฐ useTransition . (์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” experimental ์ถœ์‹œ)

    • Flux์™€ ์œ ์‚ฌํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์œ„ํ•œ ํ˜ธํ™˜์„ฑ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค. ( ์ง„ํ–‰ ์ค‘ @bvaughn , https://github.com/reactjs/rfcs/pull/147)

    • ์šฐ์„ ์ˆœ์œ„ ๋ชจ๋ธ์„ ๋ณด๋‹ค ํ•ฉ๋ฆฌ์ ์ธ ๋ชจ๋ธ๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ( ์ง„ํ–‰ ์ค‘ @acdlite , https://github.com/facebook/react/pull/18612 )

    • ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ณด๋ฅ˜ ์ค‘์ธ ์ „ํ™˜๋งŒ ์™„๋ฃŒ๋˜๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ( ์ง„ํ–‰ ์ค‘ @acdlite)

    • ์˜คํ”„์Šคํฌ๋ฆฐ API(@lunaruan ์ง„ํ–‰ ์ค‘)

    • ์„œ์ŠคํŽœ์Šค ์ฝ˜ํ…์ธ  ์ˆจ๊ธฐ๊ธฐ/ํ‘œ์‹œ ์‹œ ํ™”์žฌ ํšจ๊ณผ

    • ์˜คํ”„์Šคํฌ๋ฆฐ์— ๋Œ€ํ•œ ์ฝ˜ํ…์ธ  ์ˆจ๊ธฐ๊ธฐ/ํ‘œ์‹œ ์‹œ ํ™”์žฌ ํšจ๊ณผ

    • ํ•„์š”ํ•  ๋•Œ Portal ์ž์‹ ํ‘œ์‹œ ๋ฐ ์ˆจ๊ธฐ๊ธฐ

    • ์Šค์ผ€์ค„๋ง์„ ์œ„ํ•œ ์ง„ํ–‰ ์ค‘์ธ ํ‘œ์ค€ํ™” ์ž‘์—…์— ๋งž์ถฐ ์กฐ์ •( ์‹œ์ž‘๋˜์ง€ ์•Š์Œ )

    • ์•Œ๋ ค์ง„ ์ฃผ์š” ๋ฒ„๊ทธ ์ˆ˜์ •( @gaearon ๋ฐ @acdlite ์ง„ํ–‰ ์ค‘ )

    • ์ด๋ฒคํŠธ ์˜๋ฏธ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ( ์ง„ํ–‰ ์ค‘ @sebmarkbage @trueadm)

    • ๋ณด๋‹ค ์ ์ง„์ ์ธ ์ฑ„ํƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๋ฌธ์„œ ๋Œ€์‹  ๋ฃจํŠธ์— ์œ„์ž„( ์ง„ํ–‰ ์ค‘ , @trueadm)

    • ์บก์ฒ˜ ๋‹จ๊ณ„์—์„œ ๊ฐœ๋ณ„ ์ด๋ฒคํŠธ๋ฅผ ํ”Œ๋Ÿฌ์‹œํ•ฉ๋‹ˆ๋‹ค.

    • ๋ช…๋ นํ˜• ์ฝ”๋“œ๋ฅผ ๋” ์ž˜ ์‚ฌ์šฉํ•˜๋ ค๋ฉด event ์—์„œ ๊ธฐ๋ณธ ์šฐ์„  ์ˆœ์œ„๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

    • ๋‹ค๋ฅธ API ์˜๋ฏธ ๋ฐ ๊ธฐ๋ณธ๊ฐ’์„ ๋งˆ๋ฌด๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ( ์‹œ์ž‘๋˜์ง€ ์•Š์Œ )

    • ํƒ€์ดํ•‘๊ณผ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์‹ญ์‹œ์˜ค.

  • ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ์— ๋Œ€ํ•œ ์ค‘๋‹จ

    • ๊ตฌ์„ฑ ์š”์†Œ ์‹ ํ˜ธ์— ๋Œ€ํ•œ ์ €์ˆ˜์ค€ ์ง€์›์€ ๋ Œ๋”๋งํ•  ์ค€๋น„๊ฐ€ ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค(๊ธฐ์ˆ ์ ์œผ๋กœ ์•ˆ์ •์ ์ธ React์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ํ•˜์ง€๋งŒ ์ด API๋Š” ์•ˆ์ •์ ์ธ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค).

    • ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ๋Š” Suspense ํด๋ฐฑ์„ ์ฆ‰์‹œ ํ”Œ๋Ÿฌ์‹œํ•ฉ๋‹ˆ๋‹ค(์‹คํ—˜ ๋ฆด๋ฆฌ์Šค์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ).

    • GraphQL ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•œ ์†”๋ฃจ์…˜ (๋ฆด๋ ˆ์ด ํ›„ํฌ, ์ œ๊ณต).

    • ๋น„ GraphQL ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์œ„ํ•œ ์†”๋ฃจ์…˜( Next.js ์™€ ๊ณต๋™์œผ๋กœ @sebmarkbage ์ง„ํ–‰ ์ค‘ ).

    • ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ข…์†์„ฑ์„ ์œ„ํ•œ ๋ฒˆ๋“ค๋Ÿฌ ํ†ตํ•ฉ. ( ์ง„ํ–‰ ์ค‘ )

    • ์ปจํ…์ŠคํŠธ๋ฅผ ํฌํ•จํ•œ Finalize Blocks API.

    • ์ผ๋ฐ˜ ์บ์‹ฑ ์†”๋ฃจ์…˜. ( ์‹œ์ž‘๋˜์ง€ ์•Š์Œ )

    • ์ผ์ข…์˜ ๋ผ์šฐํ„ฐ ํ†ตํ•ฉ.

๊ฑฐ์˜ "Facebook์—์„œ ํ”„๋กœ๋•์…˜ ์ค‘์ด๋ฏ€๋กœ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."์™€ ๊ฐ™์€ ๋Š๋‚Œ์ด ๋“ญ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ๋ณด์ผ ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. :-) ์šฐ๋ฆฌ๋Š” ์ง€๋‚œ ๋ช‡ ๋‹ฌ ๋™์•ˆ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋…ผ์Šคํ†ฑ์œผ๋กœ ์ž‘์—…ํ•ด ์™”์œผ๋ฉฐ ๋งŽ์€ ๊ธฐ์ˆ ์ ์ธ ์ธก๋ฉด์ด ์™„๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜ ๊ฑฐ์˜ ๋งˆ๋ฌด๋ฆฌ ๋‹จ๊ณ„์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ ์ž‘์—…์˜ ๋Œ€๋ถ€๋ถ„์€ ๋‘ ๊ฐ€์ง€ ๋ฒ”์ฃผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.

  • ์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์Šค์—์„œ ์ด๋ฅผ ๊ฐ•ํ™”ํ•˜๊ธฐ ์ „์— ์ดˆ๊ธฐ ์„ค๊ณ„์—์„œ ๋ฐœ๊ฒฌํ•œ ๊ฒฐํ•จ์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ์ถœ์‹œํ•œ๋‹ค๋ฉด, ์šฐ๋ฆฌ๋Š” ๋ช‡ ๋‹ฌ ์•ˆ์— ์ค‘๋Œ€ํ•œ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋”ฐ๋ผ์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ๋ฟ์ž…๋‹ˆ๋‹ค.

  • ์ƒํƒœ๊ณ„ ํ˜ธํ™˜์„ฑ ๋ฐ ์ข‹์€ ๊ธฐ๋ณธ๊ฐ’. ์˜ค๋Š˜๋‚  ์•„๋ฌด๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์„ ๋ฆด๋ฆฌ์Šคํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋“ค์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ๊ธฐ์กด ์ ‘๊ทผ ๋ฐฉ์‹์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋Œ€๋ถ€๋ถ„์˜ ์ž‘์—…(์˜ˆ: useMutableSource ํ†ตํ•œ Flux ๊ณ„์—ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€์˜ ํ˜ธํ™˜์„ฑ, ๋” ๋‚˜์€ ์ด๋ฒคํŠธ ์˜๋ฏธ ์„ ํƒ, ๊ถŒ์žฅ ์บ์‹ฑ ์ „๋žต ์ œ๊ณต)์€ ์šฐ๋ฆฌ๊ฐ€ ๋ฆด๋ฆฌ์Šคํ•œ ๊ฒƒ์„ ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ธด ๊ผฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

"์˜ค๋Š˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?"๋ผ๋Š” ์ธก๋ฉด์—์„œ... ์—„๋ฐ€ํžˆ ๋งํ•˜๋ฉด ์˜ค๋Š˜ ์ด ๋ชจ๋“  ๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š”ํ•˜๋‹ค. ํŠนํžˆ Relay Hooks์™€ Concurrent ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„์ง ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๊ณผ ์•Œ๋ ค์ง„ ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ํ˜„์žฌ ์ƒํƒœ๋Š” ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์ฑ„ํƒํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ธฐ์ค€์„ ์ถฉ์กฑํ•˜์ง€ ๋ชปํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก , ๋ฒ„๊ทธ๋‚˜ API๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ ๊บผ๋ คํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์šฐ๋ฆฌ์ฒ˜๋Ÿผ @experimental ๋ฆด๋ฆฌ์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” Facebook์ด "์™„๋ฃŒ"๋ผ๋Š” ์ธก๋ฉด์—์„œ ํŠน๋ณ„ํ•œ ์œ„์น˜์— ์žˆ๋‹ค๊ณ  ๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ •๋ฐ˜๋Œ€๋กœ ์šฐ๋ฆฌ๋Š” ์•„์ง ๋๋‚˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ตฌ์ถ•ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ๊ฒฌ๊ณ ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ธฐ ๋•Œ๋ฌธ์— ์›€์ง์ด๋Š” ๊ธฐ์ฐจ์˜ ์ƒ๋‹จ์— ๋ณ€๋™๊ณผ ๊ตฌ์ถ•์„ ๊ธฐ๊บผ์ด ๊ฐ์ˆ˜ํ•  ์šฉ์˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌด๊ฑฐ์šด dogfood๊ฐ€ ์—†์—ˆ๋‹ค๋ฉด ์šฐ๋ฆฌ๊ฐ€ 6๊ฐœ์›” ๋งŒ์— ๋ฐœ๊ฒฌํ•œ ๊ฒฐํ•จ์„ ๋ฐœ๊ฒฌํ•˜๊ณ  ์žฌ์„ค๊ณ„ํ•˜๋Š” ๋ฐ ๋ช‡ ๋…„์ด ๊ฑธ๋ ธ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์š”์•ฝํ•˜์ž๋ฉด, ํ•ด์•ผ ํ•  ์ผ์ด ๋” ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  83 ๋Œ“๊ธ€

unstable_AsyncMode ๋…ธ์ถœ(์•„๋งˆ๋„?)

์ด๊ฑฐ ์ด๋ฏธ ๋…ธ์ถœ ๋œ๊ฑฐ ์•„๋‹˜?

unstable_ ์ œ๊ฑฐ๋ฅผ ์˜๋ฏธํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฆ„ ์—†๋Š” ์ฝ”๋“œ ๋ถ„ํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์˜คํ”ˆ ์†Œ์Šค๋ฅผ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค ๐Ÿ’ฏ

[์šฐ์‚ฐ]์€(๋Š”) ๋ฌด์Šจ ๋œป์ธ๊ฐ€์š”?๐Ÿค”โ˜‚๏ธ

์ฆ‰, ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ/ํŒจํ‚ค์ง€/๋„๊ตฌ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

@ghoullier ์•Œ๊ฒ ์Šต๋‹ˆ๋‹ค , ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@acdlite , ๊ฐ€์žฅ ์ž˜ ์ค€๋น„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค. ์–ด๋–ค ์ข…๋ฅ˜์˜ ํƒ€์ž„๋ผ์ธ๋„ ์š”๊ตฌํ•˜๊ฑฐ๋‚˜ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š๊ณ  ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์ด React 16์— ํฌํ•จ๋˜๊ณ  16.3์— ํฌํ•จ๋œ ์ƒˆ๋กœ์šด Context API์™€ ๊ฐ™์ด ์ ์ง„์ ์œผ๋กœ ์‰ฝ๊ฒŒ ์ฑ„ํƒํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜์‹ญ๋‹ˆ๊นŒ?

์•„๋‹ˆ๋ฉด React๋ฅผ v17๋กœ ๋ฐ€์–ด๋ถ™์ด๊ณ  ์ฑ„ํƒํ•˜๋ ค๋ฉด ๋” ๋งŽ์€ ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

๊ท€ํ•˜์˜ ๋ชฉ๋ก์— ์žˆ๋Š” ๊ฑฐ์˜ ๋ชจ๋“  ํ•ญ๋ชฉ๊ณผ ํฌ๊ฒŒ ๊ต์ฐจํ•˜๋Š” ๋กœ๋“œ๋งต์„ ์ž‘์—… ์ค‘์ด๊ณ  ์ด๋ฅผ ๊ฐ€์žฅ ์ž˜ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์งˆ๋ฌธํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ๊ฐ€์žฅ ์ž˜ ์ค€๋น„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

(์ด ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋‹ต๋ณ€์ด ๋‹ค๋ฅธ ๊ณณ์—์„œ ๋ˆ„๋ฝ๋œ ๊ฒฝ์šฐ ์‚ฌ๊ณผ๋“œ๋ฆฝ๋‹ˆ๋‹ค)

@JedWatson ์˜ ์งˆ๋ฌธ์— ๋‹ค๋ฅธ ์งˆ๋ฌธ ์ถ”๊ฐ€:

  • ๋˜ํ•œ ์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์Šค์— ๋Œ€ํ•œ ํƒ€์ž„๋ผ์ธ์„ ์–ป์„ ํ•„์š”๊ฐ€/์—†์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜์ง€๋งŒ, ์ƒˆ๋กœ์šด ํ”„๋ฆฌ๋ฆด๋ฆฌ์ฆˆ๋ฅผ ์–ป๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅ/์œ ์šฉํ• ๊นŒ์š”? (AFAIK์˜ ์ตœ์‹  ๋ฆด๋ฆฌ์Šค๋Š” 2์›”๋ถ€ํ„ฐ 16.4.0-alpha.0911da3 ์ž…๋‹ˆ๋‹ค.)

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! โค๏ธ

IMO, ๊ทธ๋“ค์€ ์ƒ๋ฅ™ํ•˜๊ธฐ ์ „์— ์ด์ „๊ณผ ๊ฐ™์€ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์„ ์ œ๊ณตํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํฐ ๋ณ€ํ™”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋„ˆ๋ฌด ๋งŽ์ด ์ค€๋น„ํ•  ํ•„์š”๋Š” ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: redux fetch with suspense์™€ ๊ฐ™์ด ํ˜„์žฌ ๊ด€ํ–‰๊ณผ ๋‹ค๋ฅด๊ฒŒ/์ถฉ๋Œํ•  ์ˆ˜ ์žˆ๋Š” ๋งŽ์€ ๊ธฐ๋Šฅ์ด ์žˆ์ง€๋งŒ codemod ๋˜๋Š” ์‰ฌ์šด ์บก์Šํ™”๊ฐ€ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด fb์—๋Š” 3W+ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  @acdlite (ZEIT์˜ @gaearon (์•„์ด์Šฌ๋ž€๋“œ์˜ ํด๋ผ์ด์–ธํŠธ ์„œ์ŠคํŽœ์Šค์— ๋Œ€ํ•ด)์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋ฅผ ๋ณด๋ฉด ๋„ˆ๋ฌด ๋งŽ์ด ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†๊ณ  ์นจ๋žต์ ์ด์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ , ์ €์žฅ์†Œ์—์„œ 'Umbrella' ํ‚ค๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด #8830 ๋ฐ #12152์™€ ๊ฐ™์€ ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

AFAIK์˜ ์ตœ์‹  ๋ฆด๋ฆฌ์Šค๋Š” 2์›”์˜ 16.4.0-alpha.0911da3์ž…๋‹ˆ๋‹ค.

IIRC, ์ด๊ฒƒ์€ ์˜ค์ž‘๋™์ž…๋‹ˆ๊นŒ?

์ €๋Š” ํŽ˜์ด์Šค๋ถ์—์„œ ์„œ์ŠคํŽœ์Šค ๋ชจ๋“ˆ๊ณผ ์ƒˆ๋กœ์šด API๋ฅผ ์ถœ์‹œํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. @acdlite ๊ฐ€ ๋‹ค๋ฅธ Facebook ์—์„œ์˜ ๊ฒฝํ—˜์— ๋Œ€ํ•œ ์ƒ๊ฐ์„ ๊ณต์œ ํ•˜๊ณ  @JedWatson์˜ ๋ช‡ ๊ฐ€์ง€ ์งˆ๋ฌธ์— ๋‹ตํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์ด React 16์— ํฌํ•จ๋˜๊ณ  16.3์— ํฌํ•จ๋œ ์ƒˆ๋กœ์šด Context API์™€ ๊ฐ™์ด ์ ์ง„์ ์œผ๋กœ ์‰ฝ๊ฒŒ ์ฑ„ํƒํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜์‹ญ๋‹ˆ๊นŒ?

React 16 ๋˜๋Š” 17๊ณผ ํ•จ๊ป˜ ์˜ฌ์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. React ํŒ€์— ๋”ฐ๋ฅด๋ฉด ์˜ฌํ•ด ๋ง ์ด์ „์— ์ถœ์‹œ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์œผ๋ฉฐ ์ด๋Š” Facebook์—์„œ ์–ผ๋งˆ๋‚˜ ์ž˜ ์‹คํ–‰๋˜๊ณ  ๊ด€๋ จ API๊ฐ€ ์ค€๋น„๋˜์–ด ์žˆ๋Š”์ง€ ๋˜๋Š” ์•„๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ฝ”๋“œ ๋ฉด์—์„œ๋Š” ์ฑ„ํƒํ•˜๊ธฐ ์‰ฌ์šธ ๊ฒƒ์ด๋ผ๊ณ  ๋ง์”€๋“œ๋ฆฌ๊ฒŒ ๋˜์–ด ๊ธฐ์ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์šฐ๋ฆฌ๋Š” facebook์—์„œ ๊ฝค ์˜ค๋žซ๋™์•ˆ ์‹คํ—˜์„ ํ•ด์™”๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์„œ์ŠคํŽœ์Šค ๊ธฐ๋Šฅ์€ ๊ธฐ์กด ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ ๊ณ„์† ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ (๋น„๋™๊ธฐ ๋ Œ๋”๋ง๊ณผ ๊ฐ™์€) ์ถ”๊ฐ€ ๋ณ€๊ฒฝ์„ ํ†ตํ•ด ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ œ๊ณตํ•˜๋Š” ๋” ๋งŽ์€ ๋ณด๋„ˆ์Šค๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

(์˜ค๋Š˜ ์ž‘์„ฑ๋œ ์ฝ”๋“œ ์ธก๋ฉด์—์„œ ํ–ฅํ›„ React์— ๋Œ€ํ•œ ์ด๋Ÿฌํ•œ ๊ฐœ์„  ์‚ฌํ•ญ๊ณผ ํ˜ธํ™˜๋˜๊ธฐ๋ฅผ ์›ํ•˜๋Š”) ํด๋ฆฌํ•„/๊ธฐ์ˆ  ๋“ฑ์„ ๊ฐ€์žฅ ์ž˜ ์ค€๋น„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ๋‹ค์†Œ ์ ์ง„์ ์ด๊ณ  ์ ์ง„์ ์ด๋ผ๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. @NE-SmallTown์ด ๋งํ–ˆ๋“ฏ์ด ์šฐ๋ฆฌ๋Š” ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋„์ž…ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋˜ํ•œ ์šฐ๋ฆฌ๊ฐ€ ๋„ˆ๋ฌด ํฐ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŽ˜์ด์Šค๋ถ์— ๋กค์•„์›ƒํ•˜๋Š” ๊ฒƒ๋„ ๊ณ ํ†ต์Šค๋Ÿฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ง€๊ธˆ๊นŒ์ง€๋Š” ๋กค์•„์›ƒ์ด ์›ํ™œํ–ˆ์œผ๋ฉฐ ์ถ”๊ฐ€ ๋ณ€๊ฒฝ์„ ์ˆ˜ํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

@JedWatson

ํ˜„์žฌ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์ด React 16์— ํฌํ•จ๋˜๊ณ  16.3์— ํฌํ•จ๋œ ์ƒˆ๋กœ์šด Context API์™€ ๊ฐ™์ด ์ ์ง„์ ์œผ๋กœ ์‰ฝ๊ฒŒ ์ฑ„ํƒํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•˜์‹ญ๋‹ˆ๊นŒ?

์ฆ๋ถ„. ํ•ญ์ƒ ์ ์ง„์ ์œผ๋กœ :) ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด Facebook์—์„œ ์ด๊ฒƒ์„ ๋ฐฐ์†กํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

| | ํด๋ผ์ด์–ธํŠธ | ์„œ๋ฒ„ ์ธก ๋ Œ๋”๋ง |
|-----|----------------------------|-- ------------------------------------------|
| ์„œ์ŠคํŽœ์Šค | ์–ด๋””์„œ๋‚˜ ์ž‘๋™* | ๊ธฐ์กด ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ์™€ ๋™์ผํ•œ ์ œ์•ฝ ์กฐ๊ฑด |
| ๋น„๋™๊ธฐ ๋ Œ๋”๋ง | <AsyncMode> ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ ํƒ | ๊ธฐ์กด ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ์™€ ๋™์ผํ•œ ์ œ์•ฝ ์กฐ๊ฑด |

*๋™๊ธฐํ™” ๋ชจ๋“œ์—์„œ delayMs ๋Š” ํ•ญ์ƒ 0 ์ž…๋‹ˆ๋‹ค. ์ž๋ฆฌ ํ‘œ์‹œ์ž๊ฐ€ ์ฆ‰์‹œ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

Suspense๋Š” ๊ธฐ์กด ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ํ•œ๋•Œ ์šฐ๋ฆฌ๋Š” <StrictMode> ํ˜ธํ™˜์„ฑ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ๋‚ด๋ถ€ ํ…Œ์ŠคํŠธ ์ค‘์— ์—„๊ฒฉ ๋ชจ๋“œ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋Š” Suspense๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž„์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹ญ๊ณ ๊ธฐ ๋‹ฌ๊ฑ€ ๋”œ๋ ˆ๋งˆ. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ์—„๊ฒฉ ๋ชจ๋“œ ๋ฐ–์—์„œ๋„ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž๋Š” ๋น„๋™๊ธฐ ๋ Œ๋”๋ง์œผ๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•  ์ค€๋น„๊ฐ€ ๋˜๊ธฐ๋„ ์ „์— Suspense๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ํ•˜์œ„ ํŠธ๋ฆฌ๊ฐ€ ์ค€๋น„๋˜๋ฉด <AsyncMode> ๋กœ ๋ž˜ํ•‘ํ•˜์—ฌ ์˜ตํŠธ์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ƒˆ ์•ฑ์˜ ๊ฒฝ์šฐ ์ด์•ผ๊ธฐ๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„๋™๊ธฐ์‹์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋น„๋™๊ธฐ ์ „์šฉ์ธ ์ƒˆ๋กœ์šด ๋ฃจํŠธ API( ReactDOM.render ๋Œ€์ฒด)๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.

๋งŽ์€ ํƒ€์‚ฌ ํ”„๋ ˆ์ž„์›Œํฌ(Redux, Apollo, React Router...)๊ฐ€ ๋น„๋™๊ธฐ ๋ชจ๋“œ์—์„œ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋Š” ์ดˆ๊ธฐ ๋ฆด๋ฆฌ์Šค ์ดํ›„ ์–ด์ƒ‰ํ•œ ๊ธฐ๊ฐ„์ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ํ•œ๋™์•ˆ ์ž…์–‘์— ์ง€์žฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์•„์ด๋””์–ด๋Š” ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ๋„ˆ๋ฌด ๋งค๋ ฅ์ ์ด์–ด์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋น„๋™๊ธฐ ํ˜ธํ™˜ ๋Œ€์•ˆ์œผ๋กœ ์ ์‘ํ•˜๊ฑฐ๋‚˜ ๋Œ€์ฒดํ•˜๋Š” ๋ฐ ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋˜ํ•œ ๊ฐ€์žฅ ์ž˜ ์ค€๋น„ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ํŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋ชจ๋“  ๊ฒƒ์„ <StrictMode> ๊ฐ์‹ธ๊ณ  ๊ฒฝ๊ณ ๊ฐ€ ์—†๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๋ฆด๋ฆฌ์Šค๊ฐ€ ๊ฐ€๊นŒ์›Œ์ง€๋ฉด ๋” ์ž์„ธํ•œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ฐ€์ด๋“œ๊ฐ€ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

๋งŽ์€ ํƒ€์‚ฌ ํ”„๋ ˆ์ž„์›Œํฌ(Redux, Apollo, React Router...)๊ฐ€ ๋น„๋™๊ธฐ ๋ชจ๋“œ์—์„œ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋Š” ์ดˆ๊ธฐ ๋ฆด๋ฆฌ์Šค ์ดํ›„ ์–ด์ƒ‰ํ•œ ๊ธฐ๊ฐ„์ด ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Apollo๋Š” ์–ด์ƒ‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ค€๋น„๊ฐ€ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค! ๐Ÿ•บ๐Ÿ˜ณ

์ง„์‹ฌ์œผ๋กœ ์šฐ๋ฆฌ๋Š” :heart: ๋ชจ๋“  ๊ฒƒ์ด React์ด๋ฏ€๋กœ ์ดˆ๊ธฐ ๋ฆด๋ฆฌ์Šค์—์„œ ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋ถ€ํ•ฉํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์€ ์ตœ์šฐ์„  ์ˆœ์œ„์ผ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋งค์šฐ ํฅ๋ถ„๋˜๋Š” ์ผ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค! ์ด @acdlite์— ๋Œ€ํ•œ ๋ชจ๋“  ๋†€๋ผ์šด ์ž‘์—…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

Redux ํŒ€์ด React-Redux์— ๋Œ€ํ•œ ๋น„๋™๊ธฐ ํ˜ธํ™˜์„ฑ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ๋งํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

https://github.com/reduxjs/react-redux/issues/950 ์—์„œ ์ž ์žฌ์  ๋กœ๋“œ๋งต์„ ์ œ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. TL;DR:

  • React-Redux 5.1์€ ๊ฒฝ๊ณ  ์—†์ด <StrictMode> ์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค(ํ˜„์žฌ PR: https://github.com/reduxjs/react-redux/pull/980 ).
  • 6.0์€ ์ƒˆ๋กœ์šด ์ปจํ…์ŠคํŠธ API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€ ์žฌ์ž‘์„ฑ, ์ฐธ์กฐ ์ „๋‹ฌ ๋ฐ ๊ธฐํƒ€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ถ”๊ฐ€ํ•˜์ง€๋งŒ ๊ฐ€๋Šฅํ•œ ํ•œ ํ˜„์žฌ ๊ณต๊ฐœ API(์˜ˆ: <Provider> ๋ฐ connect() ). ์ด๊ฒƒ์ด ๋น„๋™๊ธฐ ๋ Œ๋”๋ง์—์„œ ์–ผ๋งˆ๋‚˜ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๊ณ  ์•ž์œผ๋กœ์˜ ์ตœ์„ ์˜ ๊ฒฝ๋กœ๋ฅผ ์•Œ์•„๋‚ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. (๋‚˜์˜ ์ด์ „ ๊ฐœ๋… ์ฆ๋ช… PR์€ https://github.com/reactjs/react-redux/pull/898 ์— ์žˆ์ง€๋งŒ 5.1 ์ž‘์—…์—์„œ ๋ฐฐ์šด ๋‹ค๋ฅธ ๊ตํ›ˆ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์‹œ ์‹คํ–‰ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.) ์ด ๋ฆด๋ฆฌ์Šค์—๋Š” ์ƒˆ๋กœ์šด ์ปจํ…์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์•„์ง ์ถœ์‹œ๋˜์ง€ ์•Š์€ "๋ผ์ดํ”„์‚ฌ์ดํด ๋ฉ”์„œ๋“œ์—์„œ ์ปจํ…์ŠคํŠธ ์ฝ๊ธฐ" PR์ด ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ตœ์†Œํ•œ React 16.5๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ทธ ํ›„์— ๋‹ค๋ฅธ React-Redux API์— ๋Œ€ํ•œ ์•„์ด๋””์–ด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ, ์˜ˆ, ์—ฌ๊ธฐ์—๋Š” ๋ Œ๋”๋ง ์†Œํ’ˆ, ์‚ฌ๋žŒ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Œ).

์šฐ๋ฆฌ๋Š” WIP์— ๋” ๋งŽ์€ ๊ด€์‹ฌ์„ ๊ฐ€์ ธ์ค˜์„œ ๊ณ ๋ง™๊ณ  ์‚ฌ๋žŒ๋“ค์ด Redux๋ฅผ React Suspense ๋ฐ ๋น„๋™๊ธฐ ๋ Œ๋”๋ง๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋” ๋งŽ์€ ํ”ผ๋“œ๋ฐฑ๊ณผ ํ† ๋ก ์„ ์ œ๊ณตํ•˜์—ฌ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์ œ๋Œ€๋กœ ๋‹ค๋ฃจ์–ด์ง€๋„๋ก ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋˜ํ•œ ์ •ํ™•ํžˆ ์–ด๋–ค ์ œ์•ฝ ์กฐ๊ฑด์œผ๋กœ ์ž‘์—…ํ•ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด React ํŒ€๊ณผ ๋” ๋งŽ์€ ํ† ๋ก ์„ ํ•˜๊ธฐ๋ฅผ ํฌ๋งํ•˜๋ฉฐ, ๋ชจ๋“  ๋ฌธ์ œ์— ๋Œ€ํ•ด ์–ด๋–ค ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์ƒ˜ํ”Œ ์•ฑ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋น„๋™๊ธฐ ๋ Œ๋”๋ง ๋ฐ ์„œ์ŠคํŽœ์Šค ์ถœ์‹œ ๊ธฐ๋Œ€

@acdlite ๋˜ํ•œ ์„œ์ŠคํŽœ์Šค ๋ฐ ๋น„๋™๊ธฐ ๋ Œ๋”๋ง์— ๋Œ€ํ•œ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค.
๋‚ด ์งˆ๋ฌธ์€ ๊ทธ๋“ค์ด ๋„์ž…๋˜๊ณ  ์ƒˆ๋กœ์šด ๋ฒ„์ „์˜ react๋กœ ์•ฑ์„ ์ž‘์„ฑํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด ๋ฐ˜์‘ API์™€ ๋ฐ˜์‘์—์„œ ์‚ฌ๋žŒ๋“ค์ด ์ฝ”๋”ฉํ•˜๋Š” ๋ฐฉ์‹๋„ ๋ณ€๊ฒฝ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ? (์„œ์ŠคํŽœ์Šค ๋ฐ ๋น„๋™๊ธฐ ๋ Œ๋”๋ง ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๊ณ„ํš์ด ์—†๋”๋ผ๋„?)

๋‚˜๋Š” ์„œ์ŠคํŽœ์Šค ๋ฐ ๋น„๋™๊ธฐ ๋ Œ๋”๋ง์œผ๋กœ ๋ฐ˜์‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋” ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ (์ผ๋ถ€ ์ƒˆ๋กœ์šด API ๋˜๋Š” ๊ธฐํƒ€ ์ œ์•ฝ์œผ๋กœ ์ธํ•ด) ํ•„์š”ํ•˜์ง€ ์•Š์€ ์‚ฌ๋žŒ๋“ค์„ ์œ„ํ•ด ์™œ ์ƒˆ๋กœ์šด ๋ฐฉ์‹์œผ๋กœ ๋ฐ˜์‘์„ ์‚ฌ์šฉํ•˜๋„๋ก ๊ฐ•์ œํ•ฉ๋‹ˆ๊นŒ? ๊ทธ๋ฆฌ๊ณ  ๊ทธ๋“ค์ด ์ง€๊ธˆ์ฒ˜๋Ÿผ ๋ฐ˜์‘ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋”ฉํ•˜๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ์„œ์ŠคํŽœ์Šค๊ฐ€ ์žˆ๋Š” ๋ฐ˜์‘ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ๋” ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ œ ๊ฐ•์—ฐ ํ›„๋ฐ˜๋ถ€๋ฅผ ๋ณผ ๊ธฐํšŒ๊ฐ€ ์žˆ์œผ์…จ๋‚˜์š”? ์ €๋Š” ๊ทธ ๋ฐ˜๋Œ€๋ผ๊ณ  ๋งํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ์— ์„œ์ŠคํŽœ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋‹ค๋ฅธ ์–ด๋–ค ๊ฒƒ(Redux, ๋กœ์ปฌ ์ƒํƒœ ๋˜๋Š” ๊ธฐํƒ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํฌํ•จ)๋ณด๋‹ค ํ›จ์”ฌ ๋œ ๊นŒ๋‹ค๋กญ์Šต๋‹ˆ๋‹ค.

@gaearon ์•ˆํ–ˆ์–ด์š”. ๋‚˜๋Š” ์ด๋ก ์ƒ์œผ๋กœ ๋” ๋ง์„ ํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ๋ฐ˜์‘์„ ์•Œ๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์ด ์ด๋ฏธ ์žˆ๋‹ค๊ณ  ์ƒ์ƒํ•ด ๋ณด์‹ญ์‹œ์˜ค. ์‚ฌ๋žŒ๋“ค์ด ๋น„๋™๊ธฐ ๋ Œ๋”๋ง ๋ฐ ์„œ์ŠคํŽœ์Šค ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด ์™œ ๊ฐ•์ œ๋กœ "์ƒˆ๋กœ์šด" ๋ฐ˜์‘์„ ๋ฐฐ์šฐ๊ฒŒ ํ•ฉ๋‹ˆ๊นŒ? ํŠนํžˆ "์ƒˆ๋กœ์šด" ๋ฐ˜์‘์ด ์‚ฌ์šฉํ•˜๊ธฐ ๋” ์–ด๋ ต๋‹ค๋ฉด? ํ•˜์ง€๋งŒ: ์ €๋Š” ์ •๋ณด๊ฐ€ ๋ถ€์กฑํ•˜์—ฌ "๋” ๊นŒ๋‹ค๋กœ์šด" ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ž˜๋ชป ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ๋‹จ์ง€ ์ œ ์ƒ๊ฐ์„ ๊ณต์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. :).

์–ด๋–ค ๋ฉด์—์„œ๋Š” ์•ฑ์˜ 10%๊ฐ€ Suspense ๋ฐ ๋น„๋™๊ธฐ ๋ Œ๋”๋ง ๊ธฐ๋Šฅ์„ ํ•„์š”๋กœ ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ 90%์˜ ๊ฒฝ์šฐ ์‚ฌ๋žŒ๋“ค์ด "์ƒˆ๋กœ์šด" ๋ฐ˜์‘์„ ๋ฐฐ์šฐ๋„๋ก ๊ฐ•์š”ํ•˜๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? ํ•˜์ง€๋งŒ ์•„์ง ์„œ์ŠคํŽœ์Šค ๋ฐ ๋น„๋™๊ธฐ ๋ Œ๋”๋ง์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋งŽ์ด ์ˆ˜์ง‘ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚ด๊ฐ€ ํ‹€๋ฆด ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด ๋ฐ๋ชจ๋ฅผ ์•„์ง ๋ณด์ง€ ์•Š์•˜๋‹ค๋ฉด ๋Œ€ํ™”๊ฐ€ ์–ด๋ ค์šธ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๋ช…ํ™•ํžˆ ํ•˜์ž๋ฉด "์ƒˆ๋กœ์šด React" ๋Š” ์—†์œผ๋ฉฐ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์€ ๊ธฐ์กด ํŒจํ„ด์„ ๊นจ๋œจ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋“ค์€ ์ฒจ๊ฐ€์ œ์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์™„์ „ํžˆ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ๊ธฐ๋Šฅ์€ ์ตœ์‹  ์ˆ˜๋ช… ์ฃผ๊ธฐ ๋ฐฉ๋ฒ• ์„ ํ•ฉ๋‹ˆ๋‹ค .

์ด๊ฒƒ์ด ๊ท€ํ•˜์˜ ์šฐ๋ ค์™€ ์ง์ ‘์ ์ธ ๊ด€๋ จ์ด ์—†์ง€๋งŒ "์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ๋” ๊นŒ๋‹ค๋กญ๋‹ค"๋Š” ๋ฐ ๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์„œ์ŠคํŽœ์Šค๊ฐ€ ํ˜„์žฌ ์กด์žฌํ•˜๋Š” ๋‹ค๋ฅธ ์–ด๋–ค ๋กœ๋”ฉ ๋ฉ”์ปค๋‹ˆ์ฆ˜๋ณด๋‹ค ์‚ฌ์šฉํ•˜๊ธฐ ํ›จ์”ฌ ๊ฐ„๋‹จํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋‚ด๊ฐ€ ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ํฅ๋ถ„๋˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ƒˆ ๊ธฐ๋Šฅ ์„ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์˜ค๋ž˜๋œ ํŒจํ„ด์€ ๊ณ„์† ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋‚ด ์ด์•ผ๊ธฐ๋ฅผ ์‹œ์ฒญ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์ด ์‹ค์ œ๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์„ ๋ณด๋ฉด ํ›จ์”ฌ ๋” ์ดํ•ด๊ฐ€ ๋  ๊ฒƒ์ด๋ผ๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค.

@gaearon

๋ชจ๋“  ์˜ค๋ž˜๋œ ํŒจํ„ด์ด ๊ณ„์† ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

ํ”ผ๋“œ๋ฐฑ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋„ค, ๊ทธ๋ ‡๊ฒŒ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๋Ÿฐ ๊ธฐ๋Šฅ์„ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ทธ ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜๊ธฐ ์ „์— ์‚ฌ์šฉํ•˜๋˜ ๋ฐฉ์‹์œผ๋กœ ์“ธ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

ํ–‰์šด์„ ๋น•๋‹ˆ๋‹ค.

Hey Dan(@gaearon), ํ—›์†Œ๋ฆฌ๋Š” ์•„๋‹ˆ์ง€๋งŒ ์•Œ์•„๋‚ด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์œ„์—์„œ ๋‹น์‹ ์€ ๋งํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ƒˆ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์˜ค๋ž˜๋œ ํŒจํ„ด์€ ๊ณ„์† ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

"์ด์ „" React์—์„œ ํ–ˆ๋˜ ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ƒˆ๋กœ์šด React์—์„œ ์ฝ”๋”ฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•”์‹œํ•˜๋Š” ๊ฒƒ์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๊ทธ๋Ÿฌ๋‚˜ ์—ฌ๊ธฐ์„œ bvaughn์€ getDerivedStateFromProps(๋˜๋Š” componentWillReceiveProps)๊ฐ€ ํ•˜๋‚˜์˜ ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค์ง€ ์•Š๋Š” ๊ทธ์˜ ์†”๋ฃจ์…˜์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋‚ด ์งˆ๋ฌธ์€ ๊ฒฐ๊ตญ ์šฐ๋ฆฌ๊ฐ€ ์ด์ „๊ณผ ๋˜‘๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ƒˆ๋กœ์šด React๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๊นŒ? ํ˜„์žฌ ๋ฐ˜์‘ํ•˜๋Š” componentWillReceiveProps์˜ AFAIK๋Š” ํ•œ ๋ฒˆ์˜ ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๊นŒ?

@giorgi-m : ์˜ˆ, ์ˆ˜๋ช… ์ฃผ๊ธฐ ๋ฐฉ์‹์ด ๋ณ€๊ฒฝ๋˜๊ณ  ์žˆ์ง€๋งŒ ์š”์ ์€ Suspense ์ž์ฒด๊ฐ€ ์˜ตํŠธ์ธ ๊ธฐ๋Šฅ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ์กด์˜ ๋ชจ๋“  React ๋ Œ๋”๋ง ๋ฐฉ๋ฒ•๊ณผ React์˜ ๋ Œ๋”๋ง ๋™์ž‘์€ ๊ทธ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ _if_ <AsyncMode> ํƒœ๊ทธ๋ฅผ ์•ฑ์˜ ์ผ๋ถ€์— ์ถ”๊ฐ€ํ•˜์—ฌ ์„ ํƒํ•˜๊ณ  _๊ทธ๋ฆฌ๊ณ _ ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ ์š”๊ตฌ ์‚ฌํ•ญ์„ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด Suspense์˜ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด _๊ทธ๋•Œ_ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ฒ ์ด์Šค์— ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์œผ๋ฉด ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@giorgi-m componentDidUpdate ๋Š” componentWillReceiveProps ๋˜๋Š” getDerivedStateFromProps ๋Œ€์‹  ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@markerikson ๊ทธ๋ž˜์„œ ๋‹น์‹ ์€ bvaughn์ด ์—ฌ๊ธฐ ์—์„œ ๋งํ•œ ๋Œ€๋กœ _getDerivedStateFromProps_๊ฐ€ ํ•œ ์—…๋ฐ์ดํŠธ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœ๋  ์ˆ˜ ์žˆ์ง€๋งŒ <AsyncMode/> ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋ฐ˜๋“œ์‹œ ๊ทธ๋Ÿฐ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.
(์ด๋Ÿฌํ•œ ์งˆ๋ฌธ์„ ํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ๋•Œ๋•Œ๋กœ ์ €์—๊ฒŒ ๋‚˜ํƒ€๋‚˜๋ฉฐ ๋ชจ๋“  ๋‚ด์šฉ์„ ๋‹ค๋ฃฐ ๋ฆฌ์†Œ์Šค๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค).

์ถ”์‹ . bvaughn์€ ๋˜ํ•œ ์—ฐ๊ฒฐ๋œ ์Šค๋ ˆ๋“œ์—์„œ ์„ ํƒ ์‚ฌํ•ญ์„ ์–ธ๊ธ‰ํ•˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ๋‚ด ์˜์‹ฌ์ด ์ œ๊ธฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋น„๋™๊ธฐ ์—…๋ฐ์ดํŠธ๋ฅผ ๋Œ€๊ธฐ์—ด์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•(์˜ˆ: ๋ Œ๋”๋Ÿฌ๋ณ„ unstable_deferredUpdates() ์•„๋‹Œ ํด๋ž˜์Šค ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ฒฝ์šฐ deferSetState() unstable_deferredUpdates() )์„ ํ•ต์‹ฌ ์ฒดํฌ๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋‚ด ์ดํ•ด์—์„œ async mode Fiber์— ๋Œ€ํ•œ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ๋Š” ๋น„๋™๊ธฐ์‹์ด๋ฏ€๋กœ ์ด๋ก ์ƒ deferSetState() ๊ฐ€ ๋ถˆํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ unstable-async/suspense ๋ฐ๋ชจ ๋Š” ๋™๊ธฐ ์—…๋ฐ์ดํŠธ์™€ ๋น„๋™๊ธฐ ์—…๋ฐ์ดํŠธ๋ฅผ ํ˜ผํ•ฉํ•˜๊ณ  async ๋ชจ๋“œ("๋ฒ”์šฉ" ๊ตฌ์„ฑ ์š”์†Œ์˜ ๊ฒฝ์šฐ)์—์„œ ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํƒ€์ž„์Šฌ๋ผ์ด์‹ฑ ์šฐ์‚ฐ ์ฒดํฌ๋ฆฌ์ŠคํŠธ์— ์žˆ์Šต๋‹ˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ ์œ ํ˜•์œผ๋กœ Promise ์ง€์›

์ด์™€ ๊ด€๋ จํ•˜์—ฌ ๋‹ค์Œ์ด ์žˆ๋Š” ๊ฒฝ์šฐ:

const PromiseType = new Promise(() => {})
class A extends Component {
    componentDidMount() {}
    componentDidUpdate() {}
    render() {
        return <div><PromiseType></PromiseType></div>
    }
}

componentDidMount ๋ฐ componentDidUpdate ์ˆ˜๋ช… ์ฃผ๊ธฐ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์‹œ์ ์— ๋Œ€ํ•œ ๊ฒฝํ—˜์  ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

  1. ๋ชจ๋“  ์ž์‹์ด ํ•ด๊ฒฐ๋˜์—ˆ์„ ๋•Œ(์•ฝ์† ํฌํ•จ), ์ด ๊ฒฝ์šฐ ์•ฝ์†์ด ํ•ด๊ฒฐ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
  2. ๋ชจ๋“  ์ง์ ‘ ํ˜ธ์ŠคํŠธ ์ž์‹์ด ๋ Œ๋”๋ง๋˜๋ฉด?

@thysultan : componentDidMount ๋ฐ componentDidUpdate ๋Š” UI ํŠธ๋ฆฌ๊ฐ€ ์™„์ „ํžˆ ๋ Œ๋”๋ง๋˜์–ด DOM์— ์ ์šฉ๋œ ์ปค๋ฐ‹ ๋‹จ๊ณ„์—์„œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ Suspense์— ๋Œ€ํ•œ ๋‚˜์˜ ์ดํ•ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋‹ต์€ A ์ธ์Šคํ„ด์Šค๊ฐ€ ์‹ค์ œ๋กœ ๋งˆ์šดํŠธ๋˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. PromiseType _did_ ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์ง€๋งŒ ์ถ”๊ฐ€ ์ž์† ์ค‘ ํ•˜๋‚˜๊ฐ€ ์ ˆ๋Œ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š๋Š” ์•ฝ์†์„ ๊ธฐ๋‹ค๋ฆฌ๋ ค๊ณ  ์‹œ๋„ํ•˜๋ฉด ๋‹ค์‹œ๋Š” ๋งˆ์šดํŠธ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ cDM ๋ฐ cDU ๋Š” ์ด๋Ÿฌํ•œ ์˜ˆ์—์„œ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

(๋ˆ„๊ตฐ๊ฐ€ ๋‚ด ๊ฐ€์ •์ด ์ž˜๋ชป๋œ ๊ฒฝ์šฐ ์ž์œ ๋กญ๊ฒŒ ์ˆ˜์ •ํ•ด ์ฃผ์„ธ์š”. :) )

์˜ˆ, componentDidMount ๋˜๋Š” componentDidUpdate ๋Š” ์ „์ฒด ํŠธ๋ฆฌ ๊ฐ€ ํ•ด๊ฒฐ๋œ ํ›„์—๋งŒ ์‹คํ–‰๋˜๋Š” ์ปค๋ฐ‹ ๋‹จ๊ณ„ ์—์„œ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด ํŠธ๋ฆฌ์—๋Š” ๋ช…์‹œ์ ์œผ๋กœ ๋ฐฐ์น˜ํ•œ ์ผ๋ถ€ ์ž๋ฆฌ ํ‘œ์‹œ์ž๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ถฉ๋ถ„ํžˆ ์˜ค๋ž˜ ๊ธฐ๋‹ค๋ฆฐ ํ›„์—๋„ ๊ทธ ์•ˆ์˜ ๋ฌด์–ธ๊ฐ€๊ฐ€ ์—ฌ์ „ํžˆ ์ผ์‹œ ์ค‘๋‹จ๋˜๋Š”์ง€ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋‹ค๋ฆ„) โ€” ํ•˜์ง€๋งŒ ์ฃผ์œ„์— ์ž๋ฆฌ ํ‘œ์‹œ์ž๊ฐ€ ์—†๋Š” ์ž์‹์„ ๋ช…์‹œ์ ์œผ๋กœ ๋ Œ๋”๋งํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. "์ค€๋น„๋˜์ง€ ์•Š์€" ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ๋†€ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์ •๋ง๋กœ ๊ณ ๋Œ€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. (์‹ฌ์ง€์–ด ๋‹น์‹ ์ด ์•„์ง ์›”๋“œ ์™€์ด๋“œ ์›น์— ์ด๊ฒƒ์˜ ์ž‘๋™ ๋ฒ„์ „์„ ์˜ฌ๋ฆฌ์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„๋‚ด๊ธฐ ์œ„ํ•ด ๋งŽ์€ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ํƒ์ƒ‰ํ–ˆ์Šต๋‹ˆ๋‹ค).

์ด ๋ฆด๋ฆฌ์Šค๋ฅผ ๋•๊ธฐ ์œ„ํ•ด ์šฐ๋ฆฌ๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์ด ์žˆ์Šต๋‹ˆ๊นŒ? :๋””

ํ”Œ๋ ˆ์ดํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋งˆ์Šคํ„ฐ์—์„œ ์ปดํŒŒ์ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. fixtures/unstable-async/suspense ์ง€์นจ ๋ณด๊ธฐ

@gaearon ์ด๊ฒƒ์ด ํ˜„์žฌ ์ƒํƒœ์˜ ํด๋ผ์ด์–ธํŠธ ์ธก์—๋งŒ ์žˆ๋Š” ๊ฒƒ์ด ๋งž

ํŽธ์ง‘, ๋‹ต์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๋ฒ”์šฉ ์•ฑ์šฉ SSR์—์„œ Suspense๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ๋กœ์„œ๋Š” ์ด๊ฒƒ์ด ํด๋ผ์ด์–ธํŠธ ์ธก์ž„์„ ์•Œ๋ ค์ฃผ๋Š” Dan์˜ ์ด ๋Œ“๊ธ€ ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ ์˜๊ฒฌ์€ SSR์— ๋Œ€ํ•œ ๊ฐ€๋Šฅํ•œ ์˜๋ฏธ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๋Š” https://www.youtube.com/watch?v=z-6JC0_cOns ๋„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์‹ค์ œ๋กœ SSR ์‚ฌ๊ฑด๊ณผ ๊ด€๋ จ๋œ ๋ช‡ ๊ฐ€์ง€ ์ž‘์—…์„ ๊ณง ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์ €๊ฐ€ํ˜• ๋ชจ๋ฐ”์ผ ์žฅ์น˜์—์„œ ์‹คํ–‰๋˜๋Š” ๋น„๋™๊ธฐ React ์•ฑ์—์„œ ์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ƒ์ƒํ•ด ๋ณด์‹ญ์‹œ์˜ค.

  1. CPU๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๋Š” ์™ธ๋ถ€ ๊ด‘๊ณ  ๋กœ๋”ฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค(๐Ÿ˜“)
  2. ์‚ฌ์šฉ์ž๊ฐ€ ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๋ฉด ๋ผ์šฐํ„ฐ๊ฐ€ ์ƒˆ ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
  3. React๋Š” ๋น„๋™๊ธฐ ๋ชจ๋“œ์ด๋ฏ€๋กœ Chrome/Safari์—์„œ CPU ์‚ฌ์šฉ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€๋งŒ ๊ด‘๊ณ ๋Š” 3์ดˆ ๋™์•ˆ ๊ณ„์† ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค.
  4. ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•จ

์ด ๋ฌธ์ œ๋Š” Suspense์— ๋Œ€ํ•ด ๋…ผ์˜๋œ ๊ฒƒ๊ณผ ๋™์ผํ•œ <Placeholder> ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 1์ดˆ ํ›„์— ์Šคํ”ผ๋„ˆ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์ด ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€ ๊ณ ๋ ค๋˜์—ˆ์Šต๋‹ˆ๊นŒ? ๋Š๋ฆฐ ๋น„๋™๊ธฐ ๋ Œ๋”๋ง์— <Placeholder> ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

@luisherranz ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  1. React์—๋Š” ๋ชจ๋“  ์—…๋ฐ์ดํŠธ์™€ ๊ด€๋ จ๋œ ๋งˆ๊ฐ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ฆญ ๋ฐ ์ด์™€ ๊ฐ™์€ ๊ธฐํƒ€ ์ƒํ˜ธ์ž‘์šฉ์œผ๋กœ ์ธํ•œ ์—…๋ฐ์ดํŠธ๋Š” ๋ช…์‹œ์ ์œผ๋กœ ๋” ๊ธด ๊ธฐํ•œ์„ ์„ ํƒํ•˜์ง€ ์•Š๋Š” ํ•œ ~150ms ์ด๋‚ด์— ํ”Œ๋Ÿฌ์‹œ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค(์˜ˆ: ํ•„์ˆ˜์ ์ด์ง€ ์•Š์€ ์—…๋ฐ์ดํŠธ์˜ ๊ฒฝ์šฐ). ๋”ฐ๋ผ์„œ React๋Š” ๋ฌด์–ธ๊ฐ€๊ฐ€ ์Šค๋ ˆ๋“œ๋ฅผ ์žก์•„๋จน๋Š” ๊ฒฝ์šฐ ๋™๊ธฐ์ ์œผ๋กœ ํ”Œ๋Ÿฌ์‹œ๋ฅผ ๊ฐ•์ œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  2. React๋Š” ์‹ค์ œ๋กœ ๋” ์ด์ƒ requestIdleCallback ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์‹ค์ œ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” ์Šค์ผ€์ค„๋ง์— ๋Œ€ํ•ด ์ถฉ๋ถ„ํžˆ ๊ณต๊ฒฉ์ ์ด์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ •ํ™•ํ•œ ์ผ์ • ์ ‘๊ทผ ๋ฐฉ์‹๋„ ์‹œ๊ฐ„์ด ์ง€๋‚จ์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๊ฒƒ์€ ํ™•์‹คํžˆ ์šฐ๋ฆฌ๊ฐ€ ๊ด€์‹ฌ์„ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋น ๋ฅธ ๋‹ต๋ณ€์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. Dan.

  1. React์—๋Š” ๋ชจ๋“  ์—…๋ฐ์ดํŠธ์™€ ๊ด€๋ จ๋œ ๋งˆ๊ฐ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์—„์ฒญ๋‚œ. ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” API๊ฐ€ ์ด๋ฏธ ์žˆ์Šต๋‹ˆ๊นŒ?

  1. React๋Š” ์‹ค์ œ๋กœ ๋” ์ด์ƒ requestIdleCallback์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์‹ค์ œ๋กœ ๋ธŒ๋ผ์šฐ์ €๋Š” ์˜ˆ์•ฝ์— ๋Œ€ํ•ด ์ถฉ๋ถ„ํžˆ ๊ณต๊ฒฉ์ ์ด์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ทธ๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์‹คํ—˜ํ•œ ๊ฒƒ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๋•Œ๋•Œ๋กœ ์™ธ๋ถ€ ๊ด‘๊ณ ๊ฐ€ ์žˆ๊ณ  twitter ๋˜๋Š” youtube์—์„œ ํผ๊ฐ€๋Š” ๋ณต์žกํ•œ ์•ฑ์—์„œ requestIdleCallback ๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ๋ Œ๋”๋ง์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋ช‡ ์ดˆ๊ฐ€ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๐Ÿ‘.

BTW, ์šฐ๋ฆฌ์—๊ฒŒ๋Š” ์ฒซ ๋ฒˆ์งธ ๋‹ต๋ณ€๊ณผ ๊ด€๋ จ๋œ ๋˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‘ ๊ฐœ์˜ ์˜คํ”„์…‹์œผ๋กœ ์ง€์—ฐ ๋กœ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” ๋น„๋™๊ธฐ ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ณ  ๋‘ ๋ฒˆ์งธ๋Š” ๋น„๋™๊ธฐ๊ฐ€ ์™„๋ฃŒ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋™๊ธฐํ™” ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ™์€:

  1. ์‚ฌ์šฉ์ž๊ฐ€ ์•„๋ž˜๋กœ ์Šคํฌ๋กคํ•˜๋ฉด ๋ฌด๊ฑฐ์šด ์š”์†Œ(์˜ˆ: ๋ธ”๋กœ๊ทธ์˜ ๋‹ค์Œ ๊ฒŒ์‹œ๋ฌผ)์—์„œ 1200ํ”ฝ์…€์— ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ์ฒซ ๋ฒˆ์งธ ์˜คํ”„์…‹์€ ๋‹ค์Œ ๊ฒŒ์‹œ๋ฌผ์˜ ๋น„๋™๊ธฐ ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
  3. ์‚ฌ์šฉ์ž๋Š” ๊ณ„์† ์•„๋ž˜๋กœ ์Šคํฌ๋กคํ•˜๊ณ  ๋‹ค์Œ ๊ฒŒ์‹œ๋ฌผ์˜ 600px์— ์žˆ์Šต๋‹ˆ๋‹ค.
  4. ๋‘ ๋ฒˆ์งธ ์˜คํ”„์…‹ ํŠธ๋ฆฌ๊ฑฐ: ๋น„๋™๊ธฐ ๊ฒŒ์‹œ๋ฌผ์ด ์™„๋ฃŒ๋˜๋ฉด(componentDidMount ํ˜ธ์ถœ) ์•„๋ฌด ์ผ๋„ ์ผ์–ด๋‚˜์ง€ ์•Š์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ „์ฒด ๊ฒŒ์‹œ๋ฌผ์˜ ๋™๊ธฐํ™” ๋ Œ๋”๋ง์„ ํŠธ๋ฆฌ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์‹œ๊ฐ„ ๋Œ€์‹  ๋‘ ๋ฒˆ์งธ ํŠธ๋ฆฌ๊ฑฐ๋กœ ํ”Œ๋Ÿฌ์‹œ๋ฅผ ์ œ์–ดํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ง์ด ๋˜๋‚˜์š”? ๊ฐ€๋Šฅํ• ๊นŒ์š”?

ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๋Š” API๊ฐ€ ์ด๋ฏธ ์žˆ์Šต๋‹ˆ๊นŒ?

๋งˆ์Šคํ„ฐ๋ฅผ ์˜๋ฏธํ•˜๋Š”์ง€ ์•„๋‹Œ์ง€(๋น„๋™๊ธฐ ๋ชจ๋“œ๋Š” npm ๋ฆด๋ฆฌ์Šค์—์„œ ๊ณต์‹์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ) ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ๋งŒ๋ฃŒ ์‹œ๊ฐ„์€ ๋ชจ๋“  ์—…๋ฐ์ดํŠธ์— ์ž๋™์œผ๋กœ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค. ํด๋ฆญ๊ณผ ๊ฐ™์€ ์ด๋ฒคํŠธ์˜ ๊ฒฝ์šฐ ํ”„๋กœ๋•์…˜ ๋ชจ๋“œ์—์„œ ~150ms์ž…๋‹ˆ๋‹ค. ํŠน๋ณ„ํžˆ ๋ถˆ์•ˆ์ •ํ•œ API๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ง€์—ฐ๋œ(๋” ๊ธด) ์—…๋ฐ์ดํŠธ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์„ค์ •ํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์‹œ๊ฐ„ ๋Œ€์‹  ๋‘ ๋ฒˆ์งธ ํŠธ๋ฆฌ๊ฑฐ๋กœ ํ”Œ๋Ÿฌ์‹œ๋ฅผ ์ œ์–ดํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ง์ด ๋˜๋‚˜์š”? ๊ฐ€๋Šฅํ• ๊นŒ์š”?

๋„ค ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. https://github.com/oliviertassinari/react-swipeable-views/issues/453#issuecomment -417939459.

๋งˆ์Šคํ„ฐ๋ฅผ ์˜๋ฏธํ•˜๋Š”์ง€ ์•„๋‹Œ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(๋น„๋™๊ธฐ ๋ชจ๋“œ๋Š” npm ๋ฆด๋ฆฌ์Šค์—์„œ ๊ณต์‹์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ)

์˜ˆ, <unstable_AsyncMode> , flushSync ๋ฐ unstable_deferredUpdates ์™€ ํ•จ๊ป˜ npm ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

npm์— ๋Œ€ํ•œ ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์œผ๋กœ ์•ŒํŒŒ/๋ฒ ํƒ€ ๋ฒ„์ „ ์ถœ์‹œ๋ฅผ ์‹œ์ž‘ํ•˜์‹ญ์‹œ์˜ค! ๐Ÿ™

๋„ค ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋Š” ์—ฌ๊ธฐ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค: oliviertassinari/react-swipeable-views#453 (comment).

ํ›Œ๋ฅญํ•œ. unstable_deferredUpdates ์‚ฌ์šฉํ•˜๋Š” ํ˜„์žฌ ๊ตฌํ˜„๋ณด๋‹ค ํ›จ์”ฌ ๋‚ซ์Šต๋‹ˆ๋‹ค. :)

<div hidden> ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ•  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๋†€๋ผ์šด ์ผ์„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@luisherranz ์กฐ์‹ฌํ•˜์„ธ์š”. ๊ทธ๋Ÿฐ ๊ฒƒ๋“ค์€ ๋ถˆ์•ˆ์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ฒ„๊ทธ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ๋งค์šฐ ๋น„ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜ˆ: ์ค‘์š”ํ•œ ์ตœ์ ํ™” - "์žฌ๊ฐœ" - ์•„์ง ๊ตฌํ˜„๋˜์ง€ ์•Š์Œ). ์ƒˆ๋กœ์šด schedule ๋ชจ๋“ˆ( schedule.unstable_scheduleWork )์„ ์œ„ํ•ด unstable_deferredUpdates ๋„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๋„ค, ์šฐ๋ฆฌ๋Š” ์•ฑ์˜ ์ž‘์€ ๋ถ€๋ถ„์—๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ์ง‘์ค‘์ ์œผ๋กœ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์žˆ์ง€๋งŒ ์ง€๊ธˆ๊นŒ์ง€๋Š” ๋„ˆ๋ฌด ์ข‹์Šต๋‹ˆ๋‹ค :)

์ฃผ์ œ์™€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ:
requestIdleCallback ๋Š” ์ดˆ๋‹น 20๋ฒˆ๋งŒ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. 6x2 ์ฝ”์–ด Linux ์ปดํ“จํ„ฐ์˜ Chrome์—์„œ๋Š” UI ์ž‘์—…์— ์‹ค์ œ๋กœ ์œ ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
requestAnimationFrame ๋Š” ๋” ์ž์ฃผ ํ˜ธ์ถœ๋˜์ง€๋งŒ ์ด๋ฆ„์ด ์ œ์•ˆํ•˜๋Š” ์ž‘์—…์—๋งŒ ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ด์œ ๋กœ requestIdleCallback ์‚ฌ์šฉ์„ ์ค‘๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.

requestIdleCallback ๋Œ€์‹  ๋ฌด์—‡์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

์•„, ๋ฌผ๋ก ์ž…๋‹ˆ๋‹ค. ๋ฐ”๋ณด ๋‚˜. ์Šค์ผ€์ค„๋Ÿฌ ๋ชจ๋“ˆ์ด requestIdleCallback ๋Œ€์‹  ํ›„๋“œ ์•„๋ž˜์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ € API๊ฐ€ ๋ฌด์—‡์ธ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค. ์งˆ๋ฌธ์„ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์ œ์‹œํ–ˆ์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜‚

์˜ค, ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.
https://github.com/facebook/react/blob/eeb817785c771362416fd87ea7d2a1a32dde9842/packages/scheduler/src/Scheduler.js#L212 -L222

๊ทธ๊ฒƒ์€ ๋‹ค์Œ ๋‹จ๊ณ„์˜ ๋ฉ‹์ง„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•,

Suspense๋ฅผ ์ดํ•ดํ•˜๋ ค๊ณ  ํ•˜๋Š” ๋™์•ˆ Suspend ๊ตฌ์„ฑ ์š”์†Œ ๐Ÿ˜ณ๐Ÿ˜ฑ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์•ฑ์˜ ์–ด๋–ค ๋ถ€๋ถ„์ด ์‹ค์ œ๋กœ "์ผ์‹œ ์ค‘๋‹จ"๋˜์—ˆ๋Š”์ง€ ์ „ํ˜€ ๋ชจ๋ฅธ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์—์„œ ๋‚˜๋Š” ๊ธฐ๋Œ€ Title ์ฆ‰์‹œ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก Spinner 1000MS ์ดํ›„ UserData ~ 2000ms (ํ•ด๋‹น ๊ตฌ์„ฑ ์š”์†Œ๋กœ "๋กœ๋“œ"๋ฐ์ดํ„ฐ๊ฐ€ 2000ms ์†Œ์š”) ํ›„.
๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๊ฐ€ ๋ณธ ๊ฒƒ์€ Title ๊ฐ€ 1000ms ํ›„์— Spinner ์™€ ํ•จ๊ป˜ ์ฒ˜์Œ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

// longRunningOperation returns a promise that resolves after 2000ms
const UserResource = createResource(longRunningOperation);

function UserData() {
  const userData = UserResource.read(cache, "Lorem Ipsum");
  return <p>User Data: {userData}</p>;
}

function Spinner() {
  return <h1>Fallback Loading Spinner</h1>;
}

function Title() {
  return <h1>Hello World</h1>;
}

function App() {
  return (
    <React.Fragment>
      <Title />
      <Suspense maxDuration={1000} fallback={<Spinner />}>
        <UserData />
      </Suspense>
    </React.Fragment>
  );
}

unstable_createRoot(document.getElementById("mount")).render(<App />);

(React 16.6.0-alpha.8af6728์„ ์‚ฌ์šฉํ•˜๋Š” ์™„์ „ํ•œ ์˜ˆ์ œ๋Š” ์—ฌ๊ธฐ ์ฝ”๋“œ์ƒŒ๋“œ๋ฐ•์Šค

Title ์ฆ‰์‹œ ํ‘œ์‹œํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„๋งŒ "์ผ์‹œ ์ค‘์ง€"ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๋‚ด๊ฐ€ ์™„์ „ํžˆ Suspense๋ฅผ ์ž˜๋ชป ์ดํ•ด ํ–ˆ์Šต๋‹ˆ๊นŒ? (์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ์งˆ๋ฌธ์„ ํ•˜๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”)

๊ฐ์‚ฌ ํ•ด์š”!

์•ˆ๋…•ํ•˜์„ธ์š” @nilshatmann์ž…๋‹ˆ๋‹ค! ์ข‹์€ ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค!

์ œ๋ชฉ์„ ์ฆ‰์‹œ ํ‘œ์‹œํ•˜๊ณ  ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„๋งŒ "์ผ์‹œ ์ค‘์ง€"ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚ด๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดํ•ดํ–ˆ๋‹ค๋ฉด Title ์ฆ‰์‹œ ํ‘œ์‹œํ•˜๊ณ  ๋‹ค๋ฅธ ํ•ญ๋ชฉ๋งŒ "์ผ์‹œ ์ค‘๋‹จ"ํ•˜๊ธฐ ์œ„ํ•ด ์ด ์˜ˆ์ œ ์—์„œ์™€ ๊ฐ™์ด Title ๋ฅผ DOM์— ํ”Œ๋Ÿฌ์‹œํ•˜๊ธฐ ์ „์— React์— _๊ธฐ๋‹ค๋ฆฌ์ง€ ๋ง๋ผ๊ณ _ ๋ช…์‹œ์ ์œผ๋กœ ์•Œ๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. <Suspense maxDuration={0}> ์—์„œ ์ฆ‰์‹œ ๋ Œ๋”๋ง๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋Š” ๋ถ€๋ถ„์„ ๋ž˜ํ•‘ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์ €์ˆ˜์ค€ ์Šค์ผ€์ค„๋Ÿฌ ์—ญํ•™ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์ด ์‚ฌ์‹ค์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๊นŒ? ๋‚˜๋Š” ๋˜ํ•œ ์ด๊ฒƒ์„ ๋” ์ž˜ ์ดํ•ดํ•˜๊ณ  ์‹ถ์ง€๋งŒ ์ง€๊ธˆ์œผ๋กœ์„œ๋Š” ๋‹น์‹ ์˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๊ณณ์—์„œ ์‹ค์ œ๋กœ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ๋Š”์ง€ ๋“ค์œผ๋‹ˆ ํฅ๋ถ„๋ฉ๋‹ˆ๋‹ค.

(์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ์งˆ๋ฌธ์„ ํ•˜๋Š” ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”)

์žˆ๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜„ ํ™•์‹คํžˆ ์•Œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์งˆ๋ฌธ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@TejasQ ๋‚ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ์˜ˆ์ œ๋ฅผ ๋กœ๋“œํ•˜๋ฉด ํด๋ฐฑ ์Šคํ”ผ๋„ˆ๊ฐ€ ์ฆ‰์‹œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค. 1000ms ํ›„์— ๋ถˆ๋Ÿฌ์™€์•ผ ํ•˜๋Š” ๊ฒƒ ์•„๋‹Œ๊ฐ€์š”?

@TejasQ ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ @karlhorky ๊ฐ€ ๋งž์Šต๋‹ˆ๋‹ค. ์ด์ œ ์Šคํ”ผ๋„ˆ๊ฐ€ ์ฆ‰์‹œ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

์ข‹์•„! ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๋†“์ณค๋‹ค. ๋‚˜๋Š” ์‹œ๋„ํ–ˆ๋‹ค. ๐Ÿ˜‚ ๋‹ค์‹œ ํ•œ ๋ฒˆ ์‚ดํŽด๋ณด๊ณ  ๋‹ค์‹œ ์—ฐ๋ฝ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ญ”๊ฐ€ ๋†“์นœ ๊ฒŒ ํ‹€๋ฆผ์—†์–ด. ๐Ÿคทโ€โ™‚๏ธ

~์—…๋ฐ์ดํŠธ: ์—ฌ๊ธฐ์—์„œ ์•Œ์•„๋‚ด๋ ค๊ณ  ํ•˜๊ณ  ์žˆ๊ณ  ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ•จ๊ป˜ ํ•˜๊ณ  ์‹ถ์€ ์‚ฌ๋žŒ์ด ์žˆ์œผ๋ฉด ํ˜‘์—…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.~

๋‘ ๋ฒˆ์งธ ์—…๋ฐ์ดํŠธ: @philipp-spiess์™€ ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๋ณด์•˜๊ณ  ๋‚˜๋Š” ์ •๋ง๋กœ ๋‹นํ™ฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ์•„์ง๋„ ๊ทธ๊ฒƒ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค. ์ด ์‹œ์ ์—์„œ ์ด๊ฒƒ์ด ์‹ค์ œ๋กœ unstable_ ๋ฐ ์•ŒํŒŒ ๊ธฐ๋Šฅ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฒ„๊ทธ์ธ์ง€, ์•„๋‹ˆ๋ฉด ๋‹จ์ˆœํžˆ ๋‚ด๊ฐ€ ๋ณด์ง€ ๋ชปํ•˜๋Š” ํ•ญ๋ชฉ์ธ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‘ ๊ฒฝ์šฐ ๋ชจ๋‘ ํ•ต์‹ฌ ํŒ€์ด ์œ ์šฉํ•œ ๋‹ต๋ณ€์„ ์ œ๊ณตํ•˜๊ฑฐ๋‚˜ ๊ท€ํ•˜์˜ ์งˆ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ React๋ฅผ ๋” ๋‚˜์€/๋” ์ ‘๊ทผํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ทธ๋“ค์ด ๋ฌด์Šจ ๋ง์„ ํ•ด์•ผ ํ•˜๋Š”์ง€ ๋ด…์‹œ๋‹ค. ๐Ÿ˜„ ์ง€์ ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค, @nilshatmann!

์ด๊ฒƒ์€ React v16.6์˜ ์ผ๋ถ€๋กœ ์ถœ์‹œ๋˜์—ˆ์Šต๋‹ˆ๊นŒ? ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ ์€ Suspense๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

import React, {lazy, Suspense} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));

function MyComponent() (
  <Suspense fallback={<div>Loading...</div>}>
    <OtherComponent />
  </Suspense>
);

์ด๊ฒƒ์€ React v16.6์˜ ์ผ๋ถ€๋กœ ์ถœ์‹œ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?

์ง€์—ฐ ๋กœ๋”ฉ ์‚ฌ์šฉ ์‚ฌ๋ก€๋งŒ ๋™๊ธฐํ™” ๋ชจ๋“œ์—์„œ๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋™์‹œ ๋ชจ๋“œ๋Š” ์—ฌ์ „ํžˆ WIP์ž…๋‹ˆ๋‹ค.

@nilshatmann

๋‹ค์Œ ์˜ˆ์—์„œ๋Š” Title์ด ์ฆ‰์‹œ ํ‘œ์‹œ๋˜๊ณ  1000ms ํ›„์— Spinner๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  ~2000ms ํ›„์— UserData๊ฐ€ ํ‘œ์‹œ๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒํ•ฉ๋‹ˆ๋‹ค(ํ•ด๋‹น ๊ตฌ์„ฑ ์š”์†Œ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ "๋กœ๋“œ"ํ•˜๋Š” ๋ฐ 2000ms๊ฐ€ ์†Œ์š”๋จ).

maxDuration ๊ฐ€ ํ•˜๋Š” ์ผ์— ๋Œ€ํ•ด ์•ฝ๊ฐ„ ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ ํ•˜์‹œ๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ƒˆ๋กœ์šด ๋ฉ˜ํƒˆ ๋ชจ๋ธ์ด์ง€๋งŒ ์•„์ง ๋ฌธ์„œํ™”ํ•  ์‹œ๊ฐ„์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋™์‹œ ๋ชจ๋“œ๊ฐ€ ์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์Šค๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ํ•œ๋™์•ˆ ๊ณ„์† ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ›„ํฌ ์ œ์•ˆ์„ ๋ฐœํ‘œํ•œ ๊ฒƒ์„ ์ถ•ํ•˜ํ•ฉ๋‹ˆ๋‹ค. ํŒ€๊ณผ ๊ณต์œ ํ•˜๊ณ  ์‹ถ์€ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์–ผ๋งˆ ์ „์— Suspense์™€ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„ ๊ฐ€์ง„ React Async ๋ผ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ถœ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ Promise ํ™•์ธ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  isLoading, startedAt์™€ ๊ฐ™์€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ฐ reload ๋ฐ ์ทจ์†Œ์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ๋ชจ๋‘ ์„ ์–ธ์  API๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค( useAsync ํ›„ํฌ ๊ฐ€ ์ง„ํ–‰

์ด์ œ ๋‚ด ์ฃผ์š” ๊ด€์‹ฌ์‚ฌ๋Š” ์ด๊ฒƒ์ด Suspense์™€ ํ†ตํ•ฉ๋˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ React Async์˜ Suspense API๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‚ฌ์šฉ์ž์—๊ฒŒ ์นœ์ˆ™ํ•˜๊ณ  ๊ฐ„๋‹จํ•œ React Async API๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋™์‹œ์— Suspense์˜ ์ผ์ • ๊ธฐ๋Šฅ์„ ๋ฌด๋ฃŒ๋กœ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋ณธ ๋ฐ”์— ๋”ฐ๋ฅด๋ฉด, React Async API๊ฐ€ ๋” ์ถ”์ƒ์ ์ธ Suspense API์— ๋น„ํ•ด ๋” ํ•ฉ๋ฆฌ์ ์ด๊ณ  ์ ‘๊ทผํ•˜๊ธฐ ์‰ฝ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ React Async๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€์˜ ์•ฝ๊ฐ„ ๋” ์ž‘์€ ํ•˜์œ„ ์ง‘ํ•ฉ์—์„œ ์ž‘๋™ํ•˜๋Š” ๋ณด๋‹ค ๊ตฌ์ฒด์ ์ธ API๋ฅผ ์ œ๊ณตํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

React Cache ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•ด ์•Œ๊ณ  ๋†€๋ž์Šต๋‹ˆ๋‹ค. React Async์˜ ๊ฒฝ์šฐ ์˜๋„์ ์œผ๋กœ ์บ์‹œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํฌํ•จํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๋ฐ”๋‹๋ผ Promise๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ ์œ„์— ์บ์‹ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์ƒ๋‹นํžˆ ์‰ฝ์Šต๋‹ˆ๋‹ค.

๋งˆ์ง€๋ง‰์œผ๋กœ ์‚ฌ์šฉ์ž ์ง€์ • ํ›„ํฌ์—์„œ Suspense ๊ธฐ๋Šฅ์— ์•ก์„ธ์Šคํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์šฐ๋ คํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ์ŠคํŽœ์Šค๋Š” ์—ฌ๋Ÿฌ ๋‚ด์žฅ ๊ตฌ์„ฑ ์š”์†Œ์— ํฌ๊ฒŒ ์˜์กดํ•˜๋Š” ๊ฒƒ ๊ฐ™์œผ๋ฏ€๋กœ ํ›„ํฌ์—์„œ ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค(์ œ ์ƒ๊ฐ์—๋Š”?). ์„œ์ŠคํŽœ์Šค ํ›„ํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ๋‘˜์„ ํ†ตํ•ฉํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์—ฌ๋ณด์„ธ์š”. Suspense/Lazy๋กœ ์ฝ”๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?
์ด์ œ renderer.create(...)toTree() throws
"toTree()๋Š” ํƒœ๊ทธ๊ฐ€ 13์ธ ๋…ธ๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•„์ง ๋ชจ๋ฆ…๋‹ˆ๋‹ค."

Suspense ์˜ ์†Œํ’ˆ maxDuration ์ด ๋™๊ธฐํ™” ๋ฐ ๋™์‹œ ๋ชจ๋“œ๊ฐ€ ์•„๋‹Œ Concurrent Mode ์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. ์•„๋ฌด๋„ ์„ค๋ช…์„ ๋„์™€์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

(์ง€๊ธˆ ๋‹น์žฅ์€) Concurrent Mode ๊ฐ€ ์ด ํŠธ๋ฆฌ๋ฅผ ์ปค๋ฐ‹ํ•˜๊ธฐ ์ „์— ๋ณด๋ฅ˜ ์ƒํƒœ๋กœ ๋‘˜ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๊ฐ„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํƒ€์ž„ ์Šฌ๋ผ์ด์‹ฑ ๋งˆ๊ฐ ๊ธฐํ•œ์„ ํšจ๊ณผ์ ์œผ๋กœ ์ œ์–ดํ•˜๋ฉฐ Sync ๋ชจ๋“œ์—์„œ๋Š” ํƒ€์ž„ ์Šฌ๋ผ์ด์‹ฑ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠธ๋ฆฌ๋ฅผ ์ปค๋ฐ‹ํ•˜๊ธฐ ์ „์— ๊ธฐ๋‹ค๋ฆฌ๋ฉด ๋ฐ˜๋“œ์‹œ ์ปค๋ฐ‹์ด ... ๋™๊ธฐํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ €๋Š” ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์œ„ํ•ด ๋‚ด๋ถ€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ Suspense๋ฅผ ์‚ฌ์šฉํ•ด ์™”์œผ๋ฉฐ ์•„์ง ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์ด์œ ๋ฅผ ๋งค์šฐ ๋นจ๋ฆฌ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ฒฐ๊ตญ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์•„๋งˆ๋„ ์บ์‹œ ๊ณต๊ธ‰์ž๋ฅผ ์ œ์™ธํ•˜๊ณ  API๊ฐ€ ํฌ๊ฒŒ ๋ณ€๊ฒฝ๋  ๊ฒƒ ๊ฐ™์ง€ ์•Š๋‹ค๋Š” ์ ์„ ๊ฐ์•ˆํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ Suspense๋Š” ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ?

์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๊ธฐ ๋‚ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ์ •๋ง ๋”์ฐํ•œ ํ›„ํฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

function useComponentList(id) {
  const incomingComponents = useSuspenseFetch(
    React.useCallback(() => getComponentAPI().listComponents(id), [id])
  )

  const map = React.useMemo(
    () =>
      Map(
        (incomingComponents || []).map(component => [component.id, component])
      ),
    [incomingComponents]
  )

  return useCacheValue(map)
}

์ด ํ›„ํฌ:

  1. ์ฃผ์–ด์ง„ ๋์ ์—์„œ ์ฃผ์–ด์ง„ ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  2. ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ImmutableJS Map์œผ๋กœ ๋ณ€ํ™˜ - ์ž ์žฌ์ ์œผ๋กœ ๋น„์šฉ์ด ๋งŽ์ด ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์—…์„ ๋ฉ”๋ชจํ•ฉ๋‹ˆ๋‹ค.
  3. useCacheValue ๋ž˜ํ•‘๋œ ์ง€๋„๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํŠนํžˆ ์–ด์ƒ‰ํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

useCacheValue ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

export default function useCacheValue(value) {
  const [state, setState] = React.useState(value)
  React.useEffect(() => {
    setState(value)
  }, [value])

  return [state, setState]
}

value ๋ณ€๊ฒฝ(๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ๊ฐ€์ ธ์™”์Œ์„ ๋‚˜ํƒ€๋ƒ„)์— ์‘๋‹ตํ•˜์ง€๋งŒ ์‚ฌ์šฉ์ž๊ฐ€ ํ•ด๋‹น ์ƒํƒœ์˜ ๋ฐ˜์‘ ์•ฑ ํ‘œํ˜„์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ํ›„ํฌ๋ผ๋Š” ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๋ฉด์—์„œ๋Š” ๋งค์šฐ ๋‚˜์œ ์บ์‹œ์ฒ˜๋Ÿผ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค(๋”ฐ๋ผ์„œ ์ด๋ฆ„).

์ด ํŒจํ„ด์ด ํ˜„์žฌ ์ƒํƒœ์—์„œ Redux์™€ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ๊ณ ๊ตฐ๋ถ„ํˆฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์•„๋‹Œ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ž‘์„ฑํ–ˆ์„ ๋•Œ์™€ ์„œ์ŠคํŽœ์Šค๊ฐ€ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์œ„ํ•ด '์ค€๋น„'๋˜์—ˆ์„ ๋•Œ ์ด๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ๋ณด์ผ์ง€์— ๋Œ€ํ•œ ๋ฐœ๊ฒฌ์ด ์žˆ์—ˆ์Šต๋‹ˆ๊นŒ? ํ˜„์žฌ๋กœ์„œ๋Š” ๋ช…๋ น์  ํ”Œ๋ž˜๊ทธ ๊ฐ€์ ธ์˜ค๊ธฐ์™€ ํ•จ๊ป˜ Redux๋ฅผ ๋‹จ๋…์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋” ํž˜๋“  ์ž‘์—…์ž…๋‹ˆ๋‹ค.

Redux์— ์ž์ฒด ํ›„ํฌ ๊ฐ€ ์žˆ์œผ๋ฉด ์ด ๋‘ ๊ฐ€์ง€๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์žˆ์–ด ๊ฐ€์žฅ ํฐ ์–ด๋ ค์›€์€ Redux๊ฐ€ ๋…ธ์ถœ๋˜์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ์ปจํ…์ŠคํŠธ์™€ ํ•จ๊ป˜ HOC๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ ์ด๋ฏ€๋กœ ์ด ์ž‘์—…์€ ํ›จ์”ฌ ๊ฐ„๋‹จํ•ด์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€๋‹ต์€ :)

Suspense๋Š” ์™ธ๋ถ€ ์บ์‹œ์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค(์ƒํƒœ์— ์˜ํ•ด ๊ตฌ๋™๋˜๋Š” Hook์ด ์•„๋‹˜ ). ๊ฐ„๋‹จํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ ์ž‘๋™ํ•˜๋Š” ๊ทธ๋Ÿฌํ•œ ์บ์‹œ์˜ ์ฐธ์กฐ ๊ตฌํ˜„์„ ์ œ๊ณตํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฆด๋ ˆ์ด๋Š” ์ž์ฒด ์บ์‹ฑ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ชจ๋“  ๋„๊ตฌ(์˜ˆ: Apollo)๋„ ํ˜ธํ™˜ ๊ฐ€๋Šฅํ•œ ์ž์ฒด ์บ์‹œ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด ๋‘ ๊ฐ€์ง€ ๊ตฌํ˜„์—์„œ ์˜๊ฐ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ์—ฐ๋ณ€์ด/๋ฌดํšจํ™”๋Š” ๋‹ต๋ณ€์ด ํ•„์š”ํ•œ ์œ ์ผํ•œ ์งˆ๋ฌธ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋˜ํ•œ ๋‹ค์Œ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šคํ”ผ๋„ˆ๋ฅผ ํ‘œ์‹œ ํ•  ์‹œ๊ธฐ , ๋งค๋‹ฌ๋ฆฐ ํŠธ๋ฆฌ ์™ธ๋ถ€์— ์žˆ์„ ์ˆ˜ ์žˆ๋Š” "์ธ๋ผ์ธ ํ‘œ์‹œ๊ธฐ"์™€ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ ํŒจํ„ด, ์กฐ์ • ๋กœ๋“œ ์ƒํƒœ(ํ•˜ํ–ฅ์‹ ์ˆœ์„œ๋กœ ์ž ๊ธˆ ํ•ด์ œํ•ด์•ผ ํ•˜๊ฑฐ๋‚˜ ์›๋ž˜ ์ƒํƒœ๋กœ ๋“ค์–ด ์˜ค๋Š” ๊ฒƒ์˜ ๊ฒฝ์šฐ) ์ค€๋น„๋จ), ๋ชฉ๋ก์˜ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ Œ๋”๋ง, ์ด๊ฒƒ์ด ๋ถ€๋ถ„ ์ˆ˜ํ™”์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ ๋“ฑ. ์šฐ๋ฆฌ๋Š” ์ด๋Ÿฌํ•œ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ์ง€๋งŒ ์•„์ง "๊ณต์‹ ๊ถŒ์žฅ ์‚ฌํ•ญ"์€ ์—†์Šต๋‹ˆ๋‹ค. ์žˆ์„ ๋•Œ ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐœํ‘œํ•˜๋Š” ๋ธ”๋กœ๊ทธ์—์„œ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์œ„ํ•œ Suspense๋Š” ์‚ฌ๋žŒ๋“ค์ด ์ต์ˆ™ํ–ˆ๋˜ ๊ฒƒ๊ณผ๋Š” ์ถฉ๋ถ„ํžˆ ๋‹ค๋ฅธ ๋ฉ˜ํƒˆ ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค. Redux์™€ ๊ฐ™์€ ๋งค์šฐ ์ œํ•œ๋˜์ง€ ์•Š์€ ๋ฉ”์ปค๋‹ˆ์ฆ˜๊ณผ ํ†ตํ•ฉ๋  ๋•Œ ๋ฐ˜๋“œ์‹œ ๊ฐ•๋ ฅํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒƒ์€ ๊ณต์ •ํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๋ญ๋ผ ๋ง์”€๋“œ๋ฆฌ๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

@gaearon "์šฐ๋ฆฌ๊ฐ€ ์ด๋Ÿฐ ์ผ์„ ํ•˜๊ณ  ์žˆ๋‹ค"๊ณ  ๋งํ•  ๋•Œ ๋‚ด๊ฐ€ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ์ด๋Ÿฌํ•œ ํ† ๋ก ์ด ๋น„๊ณต๊ฐœ๋กœ ์ง„ํ–‰๋˜๋‚˜์š”?

@gaearon๋‹˜ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค :)

@ntucker ์–ธ์ œ๋‚˜์ฒ˜๋Ÿผ ์ง„ํ–‰ ์ค‘์ธ ํ™œ๋™์„ PR๋กœ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ: https://github.com/facebook/react/pull/14717 , https://github.com/facebook/react/pull/14884 , https://github.com/facebook/react/pull/15061 , https://github.com/facebook/react/pull/15151 , https://github.com/facebook/react/pull/15272 , https://github.com/facebook/react/pull/15358 , https //github.com/facebook/react/pull/15367 ๋“ฑ. ์šฐ๋ฆฌ๋Š” ๊ฐ PR์— ๋ช‡ ๊ฐ€์ง€ ์„ค๋ช…์ ์ธ ์ •๋ณด๋ฅผ ๋„ฃ์œผ๋ ค๊ณ  ๋…ธ๋ ฅํ•˜๋ฉฐ ํ…Œ์ŠคํŠธ์—์„œ ๋™์ž‘ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹คํ—˜์— ๋Œ€ํ•œ ๋ฌธ์„œ ๋ง‰๋Œ€๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ด์œ ๋กœ ๋‚ฎ์Šต๋‹ˆ๋‹ค.

์„ ํƒํ•œ ๋ชจ๋ธ์ด ์‹ค์ œ๋กœ ์ž‘๋™ํ•œ๋‹ค๋Š” ํ™•์‹ ์ด ๋“  ํ›„์— ๋” ์ž์„ธํ•œ ์„ค๋ช…์„ ๊ฒŒ์‹œํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์‹คํ—˜์„ ๋ฐœ์ƒํ•˜๋Š” ๋Œ€๋กœ ์ž์„ธํžˆ ์„ค๋ช…ํ•œ๋‹ค๋ฉด ์šฐ๋ฆฌ๋‚˜ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ชจ๋‘์—๊ฒŒ ์ƒ์‚ฐ์ ์ด์ง€ ์•Š์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์‹คํ—˜์˜ ๋Œ€๋ถ€๋ถ„์€ ์‹คํŒจํ–ˆ์œผ๋ฉฐ, ๊ฐ๊ฐ์˜ ์‹คํ—˜์„ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์„ค๋ช…ํ•˜๋ฉด ์ž‘์—… ์†๋„๊ฐ€ ๋Š๋ ค์ง‘๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์‚ฌ๋žŒ๋“ค์ด ๋‚˜์ค‘์— ์šฐ๋ฆฌ๊ฐ€ ์›๋ž˜ ์„ค๊ณ„๋œ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ซ๋Š” ๊ฒƒ์„ ์ค‘์‹ฌ์œผ๋กœ ๋ฉ˜ํƒˆ ๋ชจ๋ธ์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๋‚ณ๋Š” ๊ฒฝ์šฐ๊ฐ€ ํ›จ์”ฌ ๋” ๋งŽ์Šต๋‹ˆ๋‹ค. (๋ฐฉ๊ธˆ ์‚ญ์ œํ•œ maxDuration ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.) ๋”ฐ๋ผ์„œ ๊ท€ํ•˜์˜ ์‹œ๊ฐ„๊ณผ ์‹œ๊ฐ„์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๋•Œ๊นŒ์ง€ ๋ฐ˜์ฏค ๊ตฌ์šด ์•„์ด๋””์–ด๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ฒƒ์„ ๋ณด๋ฅ˜ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ณผ๊ฑฐ์— React๋ฅผ ๊ฐœ๋ฐœํ•œ ๋ฐฉ์‹๊ณผ๋„ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฌด์–ธ๊ฐ€๊ฐ€ ์ง„์ •์œผ๋กœ ์ค€๋น„๋˜๋ฉด(์‹ฌ์ง€์–ด ๋ฉ˜ํƒˆ ๋ชจ๋ธ์˜ ์ด๋ก ์ ์ธ ์ž‘์„ฑ์„ ์œ„ํ•ด์„œ๋ผ๋„), ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์„ค๋ช…ํ•˜๋Š” ๋ฐ ๋ชจ๋“  ์ฃผ์˜๋ฅผ ์ง‘์ค‘ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์œ„ํ•œ Suspense๋Š” ์‚ฌ๋žŒ๋“ค์ด ์ต์ˆ™ํ–ˆ๋˜ ๊ฒƒ๊ณผ๋Š” ์ถฉ๋ถ„ํžˆ ๋‹ค๋ฅธ ๋ฉ˜ํƒˆ ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค. Redux์™€ ๊ฐ™์€ ๋งค์šฐ ์ œํ•œ๋˜์ง€ ์•Š์€ ๋ฉ”์ปค๋‹ˆ์ฆ˜๊ณผ ํ†ตํ•ฉ๋  ๋•Œ ๋ฐ˜๋“œ์‹œ ๊ฐ•๋ ฅํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ธฐ๋Œ€ํ•˜๋Š” ๊ฒƒ์€ ๊ณต์ •ํ•˜์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ๋ณด๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๋ญ๋ผ ๋ง์”€๋“œ๋ฆฌ๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

@gaearon ๋‹คํ–‰์Šค๋Ÿฝ๊ฒŒ๋„ Suspense์˜ ๋ฉ˜ํƒˆ ๋ชจ๋ธ์€ ์ €์™€ ์™„๋ฒฝํ•˜๊ฒŒ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค. ํผ์ฆ ์กฐ๊ฐ์ด ์ œ์ž๋ฆฌ์— ๋†“์ด๊ฒŒ ๋˜์–ด ๋งค์šฐ ๊ธฐ์ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๋…ธ๋ ฅ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

์ง€๋‚œ 11์›”์— ๋ฐœํ‘œ๋œ ๋กœ๋“œ๋งต(https://reactjs.org/blog/2018/11/27/react-16-roadmap.html)์— ๋”ฐ๋ฅด๋ฉด Suspense์˜ "๋™์‹œ" ๋ฒ„์ „์€ 2019๋…„ 2๋ถ„๊ธฐ๋กœ ์˜ˆ์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Q3 2019. Q3๊ฐ€ ์•„๋‹Œ Q3 ๋˜๋Š” Q3 ๋“ฑ์˜ ์ธก๋ฉด์—์„œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์ด๊ฒƒ์€ ๋‚ด๊ฐ€ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ์ตœ์‹  ๋กœ๋“œ๋งต ์—…๋ฐ์ดํŠธ์˜€์Šต๋‹ˆ๋‹ค. https://reactjs.org/blog/2019/08/08/react-v16.9.0.html#an -update-to-the-roadmap

์šฐ๋ฆฌ๋Š” 10์›”์— ์‹คํ—˜์ ์ธ ๋ฆด๋ฆฌ์Šค๋ฅผ ์ œ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค: https://reactjs.org/docs/concurrent-mode-intro.html. ์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ํ”„๋กœ๋•์…˜์—์„œ ์‹คํ–‰ ์ค‘์ธ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋นŒ๋“œ์ž…๋‹ˆ๋‹ค. API๋ฅผ ์กฐ์ •ํ•˜๊ณ  ๋” ๋†’์€ ์ˆ˜์ค€์˜ API๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ์ธก๋ฉด์—์„œ ์•„์ง ํ•ด์•ผ ํ•  ์ผ์ด ๋” ์žˆ์ง€๋งŒ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„œ์ŠคํŽœ์Šค๊ฐ€ ๋‚  ์ฃฝ์ด๊ณ  ์žˆ์–ด

@gaearon ํ”„๋กœ๋•์…˜์—์„œ ์‚ฌ์šฉ

์šฐ๋ฆฌ๋Š” ๋ชจ๋‘ ์ด ์ฝ”๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์‚ฌ์—…์„ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ ์—ฌ๋Ÿฌ๋ถ„์ฒ˜๋Ÿผ ๋Šช์— ๋น ์ ธ ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ์•ฝ๊ฐ„์˜ ๋ช…ํ™•์„ฑ, ๋ธ”๋กœ๊ทธ, SOMETHING์ด ์ •๋ง ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฑฐ์˜ "Facebook์—์„œ ํ”„๋กœ๋•์…˜ ์ค‘์ด๋ฏ€๋กœ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."์™€ ๊ฐ™์€ ๋Š๋‚Œ์ด ๋“ญ๋‹ˆ๋‹ค.

@mschipperheyn

์ด๊ฒƒ์€ ๋‹ค๋…„๊ฐ„์˜ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ์ •์งํ•œ ๋Œ€๋‹ต์€ ์šฐ๋ฆฌ๊ฐ€ 2๋…„ ์ „์— ์‹œ์ž‘ํ–ˆ์„ ๋•Œ ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋งŽ์€ ์ž‘์—…์„ ๋‚ณ์•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ข‹์€ ์†Œ์‹์€ ์ด์ œ ํ”„๋กœ๋•์…˜์—์„œ ๋งŽ์ด ์‚ฌ์šฉ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ˆ„๋ฝ๋œ ๋ถ€๋ถ„์ด ๋ช…ํ™•ํ•˜๊ณ  ํ„ฐ๋„์˜ ๋์ด ๋ณด์ž…๋‹ˆ๋‹ค. ์ด๋ก ์ ์ธ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์ฑ„ํƒํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ํŽธ์•ˆํ•˜๊ฒŒ ๋งํ•  ์ˆ˜ ์žˆ๊ธฐ ์ „์— ์™„๋ฃŒํ•ด์•ผ ํ•˜๋Š” ์œ ํ•œํ•œ ์„ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜๋‚  ๋‹ค์–‘ํ•œ ์ž‘์—… ํ๋ฆ„์˜ ๋Œ€๋žต์ ์ธ ์ƒํƒœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • <Suspense> ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ ๋ถ„ํ• ์— ๋Œ€ํ•œ API lazy . (16.6 ๋ฐ˜์‘์— ์ œ๊ณต)

    • ์•„์‹œ๋‹ค์‹œํ”ผ ์ด๋ฏธ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋™์‹œ ๋ชจ๋“œ API, ์˜ˆ: createRoot ๋ฐ useTransition . (์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋Š” experimental ์ถœ์‹œ)

    • Flux์™€ ์œ ์‚ฌํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์œ„ํ•œ ํ˜ธํ™˜์„ฑ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค. ( ์ง„ํ–‰ ์ค‘ @bvaughn , https://github.com/reactjs/rfcs/pull/147)

    • ์šฐ์„ ์ˆœ์œ„ ๋ชจ๋ธ์„ ๋ณด๋‹ค ํ•ฉ๋ฆฌ์ ์ธ ๋ชจ๋ธ๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ( ์ง„ํ–‰ ์ค‘ @acdlite , https://github.com/facebook/react/pull/18612 )

    • ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ณด๋ฅ˜ ์ค‘์ธ ์ „ํ™˜๋งŒ ์™„๋ฃŒ๋˜๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ( ์ง„ํ–‰ ์ค‘ @acdlite)

    • ์˜คํ”„์Šคํฌ๋ฆฐ API(@lunaruan ์ง„ํ–‰ ์ค‘)

    • ์„œ์ŠคํŽœ์Šค ์ฝ˜ํ…์ธ  ์ˆจ๊ธฐ๊ธฐ/ํ‘œ์‹œ ์‹œ ํ™”์žฌ ํšจ๊ณผ

    • ์˜คํ”„์Šคํฌ๋ฆฐ์— ๋Œ€ํ•œ ์ฝ˜ํ…์ธ  ์ˆจ๊ธฐ๊ธฐ/ํ‘œ์‹œ ์‹œ ํ™”์žฌ ํšจ๊ณผ

    • ํ•„์š”ํ•  ๋•Œ Portal ์ž์‹ ํ‘œ์‹œ ๋ฐ ์ˆจ๊ธฐ๊ธฐ

    • ์Šค์ผ€์ค„๋ง์„ ์œ„ํ•œ ์ง„ํ–‰ ์ค‘์ธ ํ‘œ์ค€ํ™” ์ž‘์—…์— ๋งž์ถฐ ์กฐ์ •( ์‹œ์ž‘๋˜์ง€ ์•Š์Œ )

    • ์•Œ๋ ค์ง„ ์ฃผ์š” ๋ฒ„๊ทธ ์ˆ˜์ •( @gaearon ๋ฐ @acdlite ์ง„ํ–‰ ์ค‘ )

    • ์ด๋ฒคํŠธ ์˜๋ฏธ๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. ( ์ง„ํ–‰ ์ค‘ @sebmarkbage @trueadm)

    • ๋ณด๋‹ค ์ ์ง„์ ์ธ ์ฑ„ํƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ๋ฌธ์„œ ๋Œ€์‹  ๋ฃจํŠธ์— ์œ„์ž„( ์ง„ํ–‰ ์ค‘ , @trueadm)

    • ์บก์ฒ˜ ๋‹จ๊ณ„์—์„œ ๊ฐœ๋ณ„ ์ด๋ฒคํŠธ๋ฅผ ํ”Œ๋Ÿฌ์‹œํ•ฉ๋‹ˆ๋‹ค.

    • ๋ช…๋ นํ˜• ์ฝ”๋“œ๋ฅผ ๋” ์ž˜ ์‚ฌ์šฉํ•˜๋ ค๋ฉด event ์—์„œ ๊ธฐ๋ณธ ์šฐ์„  ์ˆœ์œ„๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

    • ๋‹ค๋ฅธ API ์˜๋ฏธ ๋ฐ ๊ธฐ๋ณธ๊ฐ’์„ ๋งˆ๋ฌด๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ( ์‹œ์ž‘๋˜์ง€ ์•Š์Œ )

    • ํƒ€์ดํ•‘๊ณผ ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์‹ญ์‹œ์˜ค.

  • ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ์— ๋Œ€ํ•œ ์ค‘๋‹จ

    • ๊ตฌ์„ฑ ์š”์†Œ ์‹ ํ˜ธ์— ๋Œ€ํ•œ ์ €์ˆ˜์ค€ ์ง€์›์€ ๋ Œ๋”๋งํ•  ์ค€๋น„๊ฐ€ ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค(๊ธฐ์ˆ ์ ์œผ๋กœ ์•ˆ์ •์ ์ธ React์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ํ•˜์ง€๋งŒ ์ด API๋Š” ์•ˆ์ •์ ์ธ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค).

    • ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ๋Š” Suspense ํด๋ฐฑ์„ ์ฆ‰์‹œ ํ”Œ๋Ÿฌ์‹œํ•ฉ๋‹ˆ๋‹ค(์‹คํ—˜ ๋ฆด๋ฆฌ์Šค์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ).

    • GraphQL ์‚ฌ์šฉ ์‚ฌ๋ก€์— ๋Œ€ํ•œ ์†”๋ฃจ์…˜ (๋ฆด๋ ˆ์ด ํ›„ํฌ, ์ œ๊ณต).

    • ๋น„ GraphQL ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์œ„ํ•œ ์†”๋ฃจ์…˜( Next.js ์™€ ๊ณต๋™์œผ๋กœ @sebmarkbage ์ง„ํ–‰ ์ค‘ ).

    • ๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ข…์†์„ฑ์„ ์œ„ํ•œ ๋ฒˆ๋“ค๋Ÿฌ ํ†ตํ•ฉ. ( ์ง„ํ–‰ ์ค‘ )

    • ์ปจํ…์ŠคํŠธ๋ฅผ ํฌํ•จํ•œ Finalize Blocks API.

    • ์ผ๋ฐ˜ ์บ์‹ฑ ์†”๋ฃจ์…˜. ( ์‹œ์ž‘๋˜์ง€ ์•Š์Œ )

    • ์ผ์ข…์˜ ๋ผ์šฐํ„ฐ ํ†ตํ•ฉ.

๊ฑฐ์˜ "Facebook์—์„œ ํ”„๋กœ๋•์…˜ ์ค‘์ด๋ฏ€๋กœ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."์™€ ๊ฐ™์€ ๋Š๋‚Œ์ด ๋“ญ๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ๋ณด์ผ ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. :-) ์šฐ๋ฆฌ๋Š” ์ง€๋‚œ ๋ช‡ ๋‹ฌ ๋™์•ˆ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด ๋…ผ์Šคํ†ฑ์œผ๋กœ ์ž‘์—…ํ•ด ์™”์œผ๋ฉฐ ๋งŽ์€ ๊ธฐ์ˆ ์ ์ธ ์ธก๋ฉด์ด ์™„๋ฃŒ๋˜์—ˆ๊ฑฐ๋‚˜ ๊ฑฐ์˜ ๋งˆ๋ฌด๋ฆฌ ๋‹จ๊ณ„์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ ์ž‘์—…์˜ ๋Œ€๋ถ€๋ถ„์€ ๋‘ ๊ฐ€์ง€ ๋ฒ”์ฃผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.

  • ์•ˆ์ •์ ์ธ ๋ฆด๋ฆฌ์Šค์—์„œ ์ด๋ฅผ ๊ฐ•ํ™”ํ•˜๊ธฐ ์ „์— ์ดˆ๊ธฐ ์„ค๊ณ„์—์„œ ๋ฐœ๊ฒฌํ•œ ๊ฒฐํ•จ์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ์ถœ์‹œํ•œ๋‹ค๋ฉด, ์šฐ๋ฆฌ๋Š” ๋ช‡ ๋‹ฌ ์•ˆ์— ์ค‘๋Œ€ํ•œ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋”ฐ๋ผ์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ๋ฟ์ž…๋‹ˆ๋‹ค.

  • ์ƒํƒœ๊ณ„ ํ˜ธํ™˜์„ฑ ๋ฐ ์ข‹์€ ๊ธฐ๋ณธ๊ฐ’. ์˜ค๋Š˜๋‚  ์•„๋ฌด๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์„ ๋ฆด๋ฆฌ์Šคํ•˜๋Š” ๊ฒƒ์€ ๊ทธ๋“ค์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ๊ธฐ์กด ์ ‘๊ทผ ๋ฐฉ์‹์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋„์›€์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋Œ€๋ถ€๋ถ„์˜ ์ž‘์—…(์˜ˆ: useMutableSource ํ†ตํ•œ Flux ๊ณ„์—ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€์˜ ํ˜ธํ™˜์„ฑ, ๋” ๋‚˜์€ ์ด๋ฒคํŠธ ์˜๋ฏธ ์„ ํƒ, ๊ถŒ์žฅ ์บ์‹ฑ ์ „๋žต ์ œ๊ณต)์€ ์šฐ๋ฆฌ๊ฐ€ ๋ฆด๋ฆฌ์Šคํ•œ ๊ฒƒ์„ ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๊ธด ๊ผฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

"์˜ค๋Š˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?"๋ผ๋Š” ์ธก๋ฉด์—์„œ... ์—„๋ฐ€ํžˆ ๋งํ•˜๋ฉด ์˜ค๋Š˜ ์ด ๋ชจ๋“  ๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š”ํ•˜๋‹ค. ํŠนํžˆ Relay Hooks์™€ Concurrent ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„์ง ์ค‘์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๊ณผ ์•Œ๋ ค์ง„ ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ํ˜„์žฌ ์ƒํƒœ๋Š” ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์ฑ„ํƒํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ธฐ์ค€์„ ์ถฉ์กฑํ•˜์ง€ ๋ชปํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก , ๋ฒ„๊ทธ๋‚˜ API๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ ๊บผ๋ คํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์šฐ๋ฆฌ์ฒ˜๋Ÿผ @experimental ๋ฆด๋ฆฌ์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” Facebook์ด "์™„๋ฃŒ"๋ผ๋Š” ์ธก๋ฉด์—์„œ ํŠน๋ณ„ํ•œ ์œ„์น˜์— ์žˆ๋‹ค๊ณ  ๋งํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ •๋ฐ˜๋Œ€๋กœ ์šฐ๋ฆฌ๋Š” ์•„์ง ๋๋‚˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ตฌ์ถ•ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ๊ฒฌ๊ณ ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ธฐ ๋•Œ๋ฌธ์— ์›€์ง์ด๋Š” ๊ธฐ์ฐจ์˜ ์ƒ๋‹จ์— ๋ณ€๋™๊ณผ ๊ตฌ์ถ•์„ ๊ธฐ๊บผ์ด ๊ฐ์ˆ˜ํ•  ์šฉ์˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌด๊ฑฐ์šด dogfood๊ฐ€ ์—†์—ˆ๋‹ค๋ฉด ์šฐ๋ฆฌ๊ฐ€ 6๊ฐœ์›” ๋งŒ์— ๋ฐœ๊ฒฌํ•œ ๊ฒฐํ•จ์„ ๋ฐœ๊ฒฌํ•˜๊ณ  ์žฌ์„ค๊ณ„ํ•˜๋Š” ๋ฐ ๋ช‡ ๋…„์ด ๊ฑธ๋ ธ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์š”์•ฝํ•˜์ž๋ฉด, ํ•ด์•ผ ํ•  ์ผ์ด ๋” ์žˆ์Šต๋‹ˆ๋‹ค.

@gaearon ์—…๋ฐ์ดํŠธ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๊ทธ๋ฆฌ๊ณ  ์ œ ๋ชฉ์†Œ๋ฆฌ๊ฐ€ ํ‹€๋ ธ๋‹ค๋ฉด ์‚ฌ๊ณผ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋‚˜๋Š” ๋‚ด๊ฐ€ ๋ช‡ ๋‹ฌ ๋™์•ˆ ํŠธ์œ„ํ„ฐ๋ฅผ ๋’ค์ง€๊ณ  ์•„๋ฌด๊ฒƒ๋„ ์ฐพ์ง€ ๋ชปํ•œ ๊ฒƒ์— ์•ฝ๊ฐ„ ์‹ค๋งํ–ˆ๋‹ค๋Š” ๊ฒƒ์„ ์ธ์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ธก๋ฉด Server renderer immediately flushes Suspense fallbacks (available in experimental releases) ์€ ๊ตฌํ˜„์„ ์œ„ํ•ด Apollo Graphql๋กœ ํ…Œ์ŠคํŠธํ•  ๋•Œ ์‹œ๊ฐ„์„ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์˜ˆ, ๋„์„œ๊ด€ ์ €์ž์™€ ํ˜ธ๊ธฐ์‹ฌ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๊ฐ€์ง€๊ณ  ๋†€ ์ค€๋น„๊ฐ€ ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ˆ„๋ฝ๋œ ๋ถ€๋ถ„์€ ๋Œ€๋ถ€๋ถ„ "ํ–‰๋ณตํ•œ ๊ธธ"์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์— ๊ด€ํ•œ ๊ฒƒ์ด์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ๋ฐฐ๊ด€์€ ๊ฑฐ๊ธฐ์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ๋Š” Suspense ํด๋ฐฑ์„ ์ฆ‰์‹œ ํ”Œ๋Ÿฌ์‹œํ•ฉ๋‹ˆ๋‹ค(์‹คํ—˜ ๋ฆด๋ฆฌ์Šค์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ).

์ด๊ฒƒ์— ๋Œ€ํ•ด ์–ด๋””์—์„œ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? Concurrent Mode API Reference(์‹คํ—˜์ )๋ฅผ ๊ธฐ๋Œ€ํ–ˆ์ง€๋งŒ ์šด์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€ Next.js, Relay Hooks ๋ฐ Concurrent Mode(SSR ํฌํ•จ)๋ฅผ ํ•จ๊ป˜ ์Šคํ‹ฐ์นญํ•˜๋Š” ๋ฐ๋ชจ๊ฐ€ ์žˆ๋‹ค๋ฉด ๊ต‰์žฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ถฉ๋ถ„ํ•œ ๋ฌธ์„œ๋ฅผ ์ฐพ์„ ์ˆ˜๋งŒ ์žˆ๋‹ค๋ฉด ์šด์„ ์‹œํ—˜ํ•ด ๋ณผ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@CrocoDillon

SSR์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ๋ฌธ์„œ๋Š” ์—†์ง€๋งŒ ๋Œ€๋ถ€๋ถ„ ์ƒˆ๋กœ์šด ๊ธฐ๋ณธ ๋™์ž‘์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์„œ๋ฒ„์—์„œ ์ผ์‹œ ์ค‘๋‹จ๋  ๋•Œ๋ณด๋‹ค ์‹คํ—˜์ ์ธ ๋ฆด๋ฆฌ์Šค๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๋Œ€์‹  ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด Suspense ํด๋ฐฑ์„ ํ”Œ๋Ÿฌ์‹œํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ํด๋ผ์ด์–ธํŠธ์—์„œ createRoot(node, { hydrate: true }).render(<App />) ํ•ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์ด๋ฏธ ๋ชจ๋“  ์ƒˆ๋กœ์šด ์ˆ˜ํ™” ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์„œ์ŠคํŽœ์Šค ๊ฒฝ๊ณ„๋Š” ์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ ํด๋ฐฑ HTML์— "์ฒจ๋ถ€"๋œ ๋‹ค์Œ ํด๋ผ์ด์–ธํŠธ ๋ Œ๋”๋ง์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์ „์ฒด ์•ฑ์ด ๋กœ๋“œ ๋˜๊ธฐ ์ „์— ์ˆ˜๋ถ„ ๊ณต๊ธ‰์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. <App> ๊ฐ€ ์ถฉ์ „๋˜๋ฉด ์ˆ˜๋ถ„์„ ๊ณต๊ธ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ์ค€๋น„๋˜์ง€ ์•Š์•˜์„ ๋•Œ ์•„๋ž˜ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ผ์‹œ ์ค‘๋‹จ๋˜๋Š” ํ•œ(๊ฒŒ์œผ๋ฅธ ๊ฒƒ๊ณผ ์œ ์‚ฌ). ์ด ๊ฒฝ์šฐ React๊ฐ€ ํ•˜๋Š” ์ผ์€ ์„œ๋ฒ„ HTML ์ฝ˜ํ…์ธ ๋ฅผ ์œ ์ง€ ํ•˜๋ฉด์„œ Suspense ๊ฒฝ๊ณ„๋ฅผ "์ฒจ๋ถ€"ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์œ„ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋กœ๋“œ๋˜๋ฉด ๊ณ„์† ์ˆ˜๋ถ„ ๊ณต๊ธ‰๋ฉ๋‹ˆ๋‹ค. ์ˆ˜ํ™”๋œ ๋ถ€๋ถ„์€ ๋Œ€ํ™”ํ˜• ๋ฐ ์žฌ์ƒ ์ด๋ฒคํŠธ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ํ†ตํ•ฉ ์‹œ๋„/์˜ˆ์— ๋Œ€ํ•ด @devknoll ์—๊ฒŒ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Š” ์•„๋งˆ ์ผ๋ถ€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

react@experimental ๋ฐ react-dom@experimental ํ•˜๊ณ  next.config.js ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜์—ฌ Next.js์—์„œ ๋™์‹œ ๋ชจ๋“œ๋ฅผ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// next.config.js
module.exports = {
  experimental: {
    reactMode: 'concurrent'
  }
}

๋‹ค์Œ์€ ์ด์— ๋Œ€ํ•œ Next.js ํ† ๋ก ์ž…๋‹ˆ๋‹ค. https://github.com/zeit/next.js/discussions/10645

์„œ๋ฒ„ ๋ Œ๋”๋ง์—์„œ ์ค‘๋‹จ์„ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ(์˜ˆ: ์ •์  ์‚ฌ์ดํŠธ ์ƒ์„ฑ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ)? ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€ ๊ธฐ๋ณธ๊ฐ’์ด๋ผ๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์žฌ์ •์˜ ๊ฐ€๋Šฅํ•œ์ง€ ๊ถ๊ธˆํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์ „์ฒด ์•ฑ์ด ๋กœ๋“œ๋˜๊ธฐ ์ „์— ์ˆ˜๋ถ„ ๊ณต๊ธ‰์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ธ์ œ์ˆ˜๋ถ„์„ ๊ณต๊ธ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ์ค€๋น„๋˜์ง€ ์•Š์•˜์„ ๋•Œ ์•„๋ž˜ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์ผ์‹œ ์ค‘๋‹จ๋˜๋Š” ํ•œ(๊ฒŒ์œผ๋ฅธ ๊ฒƒ๊ณผ ์œ ์‚ฌ). ์ด ๊ฒฝ์šฐ React๊ฐ€ ํ•˜๋Š” ์ผ์€ ์„œ๋ฒ„ HTML ์ฝ˜ํ…์ธ ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ Suspense ๊ฒฝ๊ณ„๋ฅผ "์ฒจ๋ถ€"ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜์œ„ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋กœ๋“œ๋˜๋ฉด ๊ณ„์† ์ˆ˜๋ถ„ ๊ณต๊ธ‰๋ฉ๋‹ˆ๋‹ค. ์ˆ˜ํ™”๋œ ๋ถ€๋ถ„์€ ๋Œ€ํ™”ํ˜• ๋ฐ ์žฌ์ƒ ์ด๋ฒคํŠธ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

@gaearon ์ผ๋ฐ˜์ ์œผ๋กœ ์„œ๋ฒ„์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํด๋ผ์ด์–ธํŠธ์—์„œ๋Š” React.lazy๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๋œป์ธ๊ฐ€์š”? ์„œ๋ฒ„์—์„œ ์ „์ฒด ๋งˆํฌ์—…์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํด๋ผ์ด์–ธํŠธ์—์„œ ๊ตฌ์„ฑ ์š”์†Œ ์ฝ”๋“œ์˜ ๊ตฌ๋ฌธ ๋ถ„์„ ๋ฐ ๋ Œ๋”๋ง์ด ์ง€์—ฐ๋ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง๋œ ๋งˆํฌ์—…์ด ์—ฌ๊ธฐ์„œ ์„œ์ŠคํŽœ์Šค ํด๋ฐฑ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๊นŒ?

@robrichard ์‹ค์ œ๋กœ React.lazy ์‹œ๋„ํ•˜์ง€๋Š” ์•Š์•˜์ง€๋งŒ(FB์—์„œ ๋‹ค๋ฅธ ๋ž˜ํผ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  Next์—๋„ ์ž์ฒด ๋ฒ„์ „์ด ์žˆ์Œ) ์ด๊ฒƒ์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ํ™•์ธํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค :-) ํŠน์ • ์ œํ•œ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด props๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์œ„์— ๋ฉ”๋ชจ ๊ตฌ์ œ๊ธˆ์œต์ด ์—†๋Š” ๊ฒฝ์šฐ ๋˜๋Š” ๊ทธ ์œ„์˜ ์ปจํ…์ŠคํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒฝ์šฐ ๋ฌด์—‡์„ ํ•ด์•ผ ํ• ์ง€ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋Œ€์ฒด๋ฅผ ํ‘œ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์œผ๋กœ.

@gaearon ํ˜„์žฌ ์ƒํƒœ ๋ถ€๋ถ„์ˆ˜๋ถ„์€? #14717์ด ๋ณ‘ํ•ฉ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์–ด๋–ค ๋ฆด๋ฆฌ์Šค๋กœ ๋งŒ๋“ค์–ด์กŒ๋Š”์ง€ ์˜์‹ฌ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค.

unstable_createRoot API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•œ ์˜ค๋žซ๋™์•ˆ ๋ชจ๋“  @experimental ๋ฆด๋ฆฌ์Šค์—์„œ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฐ๋ชจ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. https://codesandbox.io/s/floral-worker-xwbwv?file=/src/index.js

@gaearon "๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ข…์†์„ฑ"์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์ž์„ธํžˆ

@gaearon "๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ข…์†์„ฑ"์ด ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋Š”์ง€ ์ž์„ธํžˆ

๋ฌผ๋ก  ์ด์ฃ . ์œ„์˜ ๋ชฉ๋ก์ด ๊ฐ„๊ฒฐํ•œ ๊ฒƒ์— ๋Œ€ํ•ด ์‚ฌ๊ณผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งค์šฐ ์••์ถ•๋˜์–ด ์žˆ๊ณ  ์ด๋“ค ์ค‘ ๋งŽ์€ ๋ถ€๋ถ„์ด ์ค‘์š”ํ•œ ๋ณ„๋„์˜ ํ•˜์œ„ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค(์ด ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค).

๊ท€ํ•˜์˜ ํŠน์ • ์งˆ๋ฌธ์— ๋‹ตํ•˜๊ธฐ ์ „์— ํ•œ ๊ฑธ์Œ ๋ฌผ๋Ÿฌ๋‚˜์„œ ์ข€ ๋” ๋„“์€ ๋งฅ๋ฝ์„ ๋ง์”€๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๋” ๋„“์€ ๋งฅ๋ฝ์€ ์ •๋ง ์ข‹์€ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์†”๋ฃจ์…˜์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์ด ์ •๋ง ์ •๋ง ์–ด๋ ต๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ตฌํ˜„์˜ ์˜๋ฏธ์—์„œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋””์ž์ธ์˜ ์˜๋ฏธ์—์„œ๋„. ์ผ๋ฐ˜์ ์œผ๋กœ ์ฝ”๋กœ์ผ€์ด์…˜(๋ฐ์ดํ„ฐ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ์œ„์น˜์— ๊ฐ€๊น๊ฒŒ ์œ ์ง€)๊ณผ ํšจ์œจ์„ฑ(๋ฐ์ดํ„ฐ ๋กœ๋“œ๋ฅผ ์–ผ๋งˆ๋‚˜ ์ผ์ฐ ์‹œ์ž‘ํ•˜๊ณ  ๋„คํŠธ์›Œํฌ ํญํฌ์ˆ˜๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š”์ง€) ๊ฐ„์— ์ ˆ์ถฉ์•ˆ์„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์†Œ๊ทœ๋ชจ์—์„œ๋Š” ๋ˆˆ์— ๋„์ง€ ์•Š์ง€๋งŒ ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ ๋›ฐ์–ด๋‚œ ์„ฑ๋Šฅ๊ณผ ์“ฐ๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ ์ค‘์—์„œ ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ๊ฒฝ์šฐ์— ๋ถˆํ–‰ํžˆ๋„ ๋‘˜ ๋‹ค ์–ป์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ๋œจ๊ฑฐ์šด ์ฃผ์ œ์ธ ์ด์œ ์ž…๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” "๊ณต์‹" React์— ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ๋งค์šฐ ๋†’์€ ๊ธฐ์ค€์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. "Reacty"๊ฐ€ ๋˜๋ ค๋ฉด ์ผ๋ฐ˜ React ๊ตฌ์„ฑ ์š”์†Œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์ˆ˜์ฒœ ๊ฐœ์˜ ๊ตฌ์„ฑ ์š”์†Œ๋กœ ํ™•์žฅ๋  ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ์ง€ ์•Š๋Š” ์†”๋ฃจ์…˜์„ ์„ ์˜๋กœ ์ถ”์ฒœํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์„ฑ๋Šฅ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ณต์žกํ•œ ์ตœ์ ํ™”๋œ ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋„๋ก ํ•˜๋Š” ์†”๋ฃจ์…˜์„ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. FB์—์„œ ์šฐ๋ฆฌ๋Š” Relay ํŒ€์œผ๋กœ๋ถ€ํ„ฐ ๋งŽ์€ ๊ตํ›ˆ์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์ด GraphQL์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฑฐ๋‚˜ Relay๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ดํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” ์ผ๋ฐ˜ React์šฉ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์†”๋ฃจ์…˜์ด Relay์—์„œ ์–ด๋ ต๊ฒŒ ์–ป์€ ๊ตํ›ˆ ์„

์ €๋Š” ์ด๊ฒƒ์ด ๋‹จ์ง€ ํฐ ์•ฑ์— ๊ด€ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋Š” ์ ์„ ๊ฐ•์กฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ํฐ ์•ฑ์—์„œ ๊ฐ€์žฅ ๋‘๋“œ๋Ÿฌ์ง€์ง€๋งŒ npm์—์„œ ๋งŽ์€ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ž‘์€ ์•ฑ๋„ ์ด๋Ÿฌํ•œ ๋น„ํšจ์œจ์„ฑ์˜ ํ•˜์œ„ ์ง‘ํ•ฉ์œผ๋กœ ์–ด๋ ค์›€์„ ๊ฒช์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋„ˆ๋ฌด ๋งŽ์€ ํด๋ผ์ด์–ธํŠธ ์ธก ์ฝ”๋“œ๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ์ด๋ฅผ ์›Œํ„ฐํด์— ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋˜๋Š” ๋„ˆ๋ฌด ๋งŽ์ด ๋ฏธ๋ฆฌ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ž‘์€ ์•ฑ์€ ์ž‘์€ ์•ฑ์œผ๋กœ ์˜์›ํžˆ ๋‚จ์•„ ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. React ๊ตฌ์„ฑ ์š”์†Œ ๋ชจ๋ธ์ด ์•ฑ์˜ ๋ณต์žก์„ฑ์— ๊ด€๊ณ„์—†์ด ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ชจ๋“  ํฌ๊ธฐ์˜ ์•ฑ์— ๋Œ€ํ•ด ์ž˜ ์ž‘๋™ํ•˜๋Š” ์†”๋ฃจ์…˜์„ ์›ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ๊ท€ํ•˜์˜ ํŠน์ • ์งˆ๋ฌธ์„ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๋ฆด๋ ˆ์ด์—๋Š” "๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ข…์†์„ฑ"์ด๋ผ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋Š” ํ•œ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์€ ๋™์  import ์˜ ์ง„ํ™”์ž…๋‹ˆ๋‹ค. ๋™์  import ์ด ํ•ญ์ƒ ํšจ์œจ์ ์ธ ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์กฐ๊ฑด์ด ์ฐธ์ผ ๋•Œ๋งŒ ์ผ๋ถ€ ์ฝ”๋“œ๋ฅผ ๋กœ๋“œํ•˜๋ ค๋Š” ๊ฒฝ์šฐ(์˜ˆ: "์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ–ˆ๋Š”์ง€" ๋˜๋Š” "์‚ฌ์šฉ์ž์—๊ฒŒ ์ฝ์ง€ ์•Š์€ ๋ฉ”์‹œ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?"), ์œ ์ผํ•œ ์˜ต์…˜์€ ๋Š๋ฆฌ๊ฒŒ ํŠธ๋ฆฌ๊ฑฐํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ๋ฌด์–ธ๊ฐ€๊ฐ€ ์‚ฌ์šฉ๋  ๋•Œ๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ(์˜ˆ: React.lazy )๋ฅผ "์‹œ์ž‘"ํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ์‚ฌ์‹ค ๋„ˆ๋ฌด ๋Šฆ์—ˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๋Ÿฌ ์ˆ˜์ค€์˜ ์ฝ”๋“œ ๋ถ„ํ•  ๊ตฌ์„ฑ ์š”์†Œ(๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ตฌ์„ฑ ์š”์†Œ)๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ๊ฐ€์žฅ ์•ˆ์ชฝ์— ์žˆ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์œ„์— ์žˆ๋Š” ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ๋กœ๋“œ๋œ ํ›„์—๋งŒ ๋กœ๋“œ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋น„ํšจ์œจ์ ์ด๋ฉฐ ๋„คํŠธ์›Œํฌ "ํญํฌ"์ž…๋‹ˆ๋‹ค. ๋ฆด๋ ˆ์ด "๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ข…์†์„ฑ"์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฟผ๋ฆฌ์˜ ์ผ๋ถ€๋กœ ๊ฐ€์ ธ์˜ค๋ ค๋Š” ๋ชจ๋“ˆ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, "์ผ๋ถ€ ์กฐ๊ฑด์ด ์ฐธ์ด๋ฉด ๋ฐ์ดํ„ฐ ์‘๋‹ต๊ณผ ํ•จ๊ป˜ ์ด ์ฝ”๋“œ ์ฒญํฌ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค". ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•„์š”ํ•œ ๋ชจ๋“  ์ฝ”๋“œ ๋ถ„ํ•  ์ฒญํฌ๋ฅผ ์ตœ๋Œ€ํ•œ ๋นจ๋ฆฌ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ฑ๋Šฅ์„ ์œ„ํ•ด ์ฝ”๋กœ์ผ€์ด์…˜์„ ๊ตํ™˜ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋ณ„ ๊ฒƒ ์•„๋‹Œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ œํ’ˆ ์ฝ”๋“œ์—์„œ ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ์ดˆ๋ฅผ ์ค„์˜€์Šต๋‹ˆ๋‹ค.

์ด์ œ ๋‹ค์‹œ, ์šฐ๋ฆฌ๋Š” Relay๋ฅผ React์— ๋„ฃ์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ ์‚ฌ๋žŒ๋“ค์ด GraphQL์„ ์‚ฌ์šฉํ•˜๋„๋ก ๊ฐ•์š”ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐœ๋…์ ์œผ๋กœ ๊ธฐ๋Šฅ ์ž์ฒด๋Š” ์ผ๋ฐ˜์ ์ด๋ฉฐ ์ด์— ๋Œ€ํ•œ ์ข‹์€ ์˜คํ”ˆ ์†Œ์Šค ์†”๋ฃจ์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ๋žŒ๋“ค์ด ์˜ค๋Š˜๋‚ ๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋งŽ์€ ์ฝ”๋“œ ๋ถ„ํ• ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋”ฐ๋ผ์„œ ํด๋ผ์ด์–ธํŠธ JS ์ฝ”๋“œ๋ฅผ ํ›จ์”ฌ ์ ๊ฒŒ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค!). ํ•ด๋‹น ์ผ๋ฐ˜ ๊ธฐ๋Šฅ์€ ํ˜ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. "๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜ ์ข…์†์„ฑ" โ€” ์ œ๊ฐ€ ์–ธ๊ธ‰ํ•œ ๋ฆด๋ ˆ์ด ์ด๋ฆ„์ผ ๋ฟ์ž…๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ GraphQL์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋” ํฐ ๊ถŒ์žฅ ์†”๋ฃจ์…˜์˜ ์ผ๋ถ€๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ๊ธ€๋จธ๋ฆฌ ๊ธฐํ˜ธ ๋ชฉ๋ก ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•  ๋‚ด์šฉ์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ๋ชฉ๋ก์—์„œ ํ•ด๋‹น ์ด๋ฆ„์œผ๋กœ ์ฐธ์กฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ํ•ด๊ฒฐ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰