2022๋…„ 3์›” 29์ผ, The React Team


์ด์ œ npm์—์„œ React 18์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ๋Š” ์•ฑ์„ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๊ณผ ๋ฏธ๋ž˜์— ์–ด๋–ค ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š”์ง€์— ๋Œ€ํ•ด ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


์ตœ์‹  ๋ฉ”์ด์ € ๋ฒ„์ „์—๋Š” ์ž๋™ batching, startTransition๊ณผ ๊ฐ™์€ ์ƒˆ๋กœ์šด API, Suspense๋ฅผ ์ง€์›ํ•˜๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง๊ณผ ๊ฐ™์€ ์ฆ‰๊ฐ์ ์ธ ๊ฐœ์„  ์‚ฌํ•ญ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

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

์šฐ๋ฆฌ๋Š” ์ˆ˜๋…„๊ฐ„ React์˜ ๋™์‹œ์„ฑ(concurrency) ์ง€์›์„ ์—ฐ๊ตฌํ•˜๊ณ  ๊ฐœ๋ฐœํ•ด ์™”์œผ๋ฉฐ, ๊ธฐ์กด ์‚ฌ์šฉ์ž๊ฐ€ ์ ์ง„์ ์œผ๋กœ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ๋ณ„ํžˆ ์‹ ๊ฒฝ์„ ์ผ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ์—ฌ๋ฆ„์—๋Š” ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ์ „๋ฌธ๊ฐ€๋“ค๋กœ๋ถ€ํ„ฐ ํ”ผ๋“œ๋ฐฑ์„ ์ˆ˜์ง‘ํ•˜๊ณ  ์ „์ฒด React ์ƒํƒœ๊ณ„๋ฅผ ์œ„ํ•œ ์›ํ™œํ•œ ์—…๊ทธ๋ ˆ์ด๋“œ ํ™˜๊ฒฝ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด React 18 Working Group์„ ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

๋†“์น˜์‹  ๋ถ„๋“ค์„ ์œ„ํ•ด React Conf 2021์—์„œ ๋งŽ์€ ๋ถ€๋ถ„์„ ๊ณต์œ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ Concurrent ๋ Œ๋”๋ง๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ ์ด๋ฒˆ ๋ฆด๋ฆฌ์Šค์—์„œ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ „์ฒด ๊ฐœ์š”์ž…๋‹ˆ๋‹ค.

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

React Native ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ด React 18์€ ์ƒˆ๋กœ์šด React Native ์•„ํ‚คํ…์ฒ˜์™€ ํ•จ๊ป˜ React Native๋กœ ์ œ๊ณต๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ React Conf ํ‚ค๋…ธํŠธ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

React์˜ Concurrent์ด๋ž€?

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

Concurrency ์ž์ฒด๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹™๋‹ˆ๋‹ค. React๊ฐ€ ๋™์‹œ์— ์—ฌ๋Ÿฌ ๋ฒ„์ „์˜ UI๋ฅผ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ƒˆ๋กœ์šด ๋น„ํ•˜์ธ๋“œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. Concurrency๋Š” ๊ตฌํ˜„์˜ ์„ธ๋ถ€ ์‚ฌํ•ญ์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, concurrency๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ ๋•Œ๋ฌธ์— ๊ฐ€์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. React๋Š” ๋‚ด๋ถ€ ๊ตฌํ˜„์—์„œ ์šฐ์„ ์ˆœ์œ„ ํ์™€ ๋‹ค์ค‘ ๋ฒ„ํผ๋ง๊ณผ ๊ฐ™์€ ์ •๊ตํ•œ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ์˜ ๊ณต๊ฐœ API์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๊ฐœ๋…์„ ์ฐพ์•„๋ณผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

API๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์šฐ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์ˆจ๊ธฐ๋ ค๊ณ  ๋…ธ๋ ฅํ•ฉ๋‹ˆ๋‹ค. React ๊ฐœ๋ฐœ์ž๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์–ด๋–ค ๋ชจ์Šต(what) ์œผ๋กœ ๋งŒ๋“ค ๊ฒƒ์ธ์ง€์— ์ง‘์ค‘ํ•˜๊ณ , React๋Š” ๊ทธ ๊ฒฝํ—˜์„ ์–ด๋–ป๊ฒŒ(how) ์ „๋‹ฌํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ React ๊ฐœ๋ฐœ์ž๊ฐ€ ๋‚ด๋ถ€์—์„œ concurrency๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์•Œ๊ธฐ๋ฅผ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ Concurrent React๋Š” ์ผ๋ฐ˜์ ์ธ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ๋ณด๋‹ค ๋” ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด React์˜ ํ•ต์‹ฌ ๋ Œ๋”๋ง ๋ชจ๋ธ์— ๋Œ€ํ•œ ๊ทผ๋ณธ์ ์ธ ์—…๋ฐ์ดํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ concurrency๊ฐ€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์•„๋Š” ๊ฒƒ์ด ์—„์ฒญ๋‚˜๊ฒŒ ์ค‘์š”ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ๋†’์€ ์ˆ˜์ค€์—์„œ concurrency๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•„๋Š” ๊ฒƒ์€ ๊ฐ€์น˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

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

๋˜ ๋‹ค๋ฅธ ์˜ˆ๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. Concurrent React๋Š” ํ™”๋ฉด์—์„œ UI์˜ ์„น์…˜์„ ์ œ๊ฑฐํ–ˆ๋‹ค๊ฐ€ ๋‚˜์ค‘์— ๋‹ค์‹œ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ ์ด์ „ ์ƒํƒœ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ ๋ฒ—์–ด๋‚˜ ๋’ค๋กœ ํƒญ ํ•  ๋•Œ, React๋Š” ํ™”๋ฉด์„ ์ด์ „๊ณผ ๋™์ผํ•œ ์ƒํƒœ๋กœ ๋ณต์›ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ณง ์ถœ์‹œ๋  ๋งˆ์ด๋„ˆ ๋ฒ„์ „์—์„œ๋Š” ์ด ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๋Š” <Offscreen>์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”๊ฐ€ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Offscreen์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋ณด๊ธฐ ์ „์— ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ƒˆ UI๋ฅผ ์ค€๋น„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Concurrent ๋ Œ๋”๋ง์€ React์˜ ๊ฐ•๋ ฅํ•œ ์ƒˆ ๋„๊ตฌ์ด๋ฉฐ Suspense, Transitions, ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง ๋“ฑ ๋Œ€๋ถ€๋ถ„์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ด๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ React 18์€ ์šฐ๋ฆฌ๊ฐ€ ์ด ์ƒˆ๋กœ์šด ๊ธฐ๋ฐ˜ ์œ„์— ๊ตฌ์ถ•ํ•˜๊ณ ์ž ํ•˜๋Š” ๋ชฉํ‘œ์˜ ์‹œ์ž‘์ผ ๋ฟ์ž…๋‹ˆ๋‹ค.

์ ์ง„์ ์œผ๋กœ Concurrent ๊ธฐ๋Šฅ ์ ์šฉํ•˜๊ธฐ

๊ธฐ์ˆ ์ ์œผ๋กœ concurrent ๋ Œ๋”๋ง์€ ํš๊ธฐ์ ์ธ ๋ณ€ํ™”์ž…๋‹ˆ๋‹ค. Concurrent ๋ Œ๋”๋ง์€ ์ค‘๋‹จ์ด ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์•ฝ๊ฐ„ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

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

์ „๋ฐ˜์ ์ธ ์—…๊ทธ๋ ˆ์ด๋“œ ์ „๋žต์€ ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ํ›ผ์†ํ•˜์ง€ ์•Š๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ React 18์—์„œ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ž์‹ ์˜ ์†๋„์— ๋งž์ถฐ ์ ์ง„์ ์œผ๋กœ concurrent ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ์ค‘์— concurrency ๊ด€๋ จ ๋ฒ„๊ทธ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๋Š” <StrictMode>๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Strict ๋ชจ๋“œ๋Š” ํ”„๋กœ๋•์…˜ ๋™์ž‘์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์ง€๋งŒ, ๊ฐœ๋ฐœ ์ค‘์— ์ถ”๊ฐ€ ๊ฒฝ๊ณ ๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ๋น„ํ™œ์„ฑํ™”๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ด์ค‘ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์„ ์žก์•„๋‚ด์ง€๋Š” ๋ชปํ•˜์ง€๋งŒ ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์œ ํ˜•์˜ ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋ฉด ์ฆ‰์‹œ concurrent ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด startTransition์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ํ™”๋ฉด ์‚ฌ์ด๋ฅผ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๋ฆฌ๋ Œ๋”๋ง์„ ์Šค๋กœํ‹€๋งํ•˜๊ธฐ ์œ„ํ•ด useDeferredValue๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์žฅ๊ธฐ์ ์œผ๋กœ๋Š” ์•ฑ์— concurrency๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ฃผ๋œ ๋ฐฉ๋ฒ•์€ concurrency ์ง€์› ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ concurrent API์™€ ์ง์ ‘ ์ƒํ˜ธ ์ž‘์šฉํ•˜์ง€๋Š” ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ƒˆ ํ™”๋ฉด์œผ๋กœ ์ด๋™ํ•  ๋•Œ๋งˆ๋‹ค startTransition์„ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹ , ๋ผ์šฐํ„ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ž๋™์œผ๋กœ startTransition์— ๋‚ด๋น„๊ฒŒ์ด์…˜์„ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค.

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

๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด์ „ ๊ฒŒ์‹œ๋ฌผ์„ ์ฐธ์กฐํ•˜์„ธ์š”. React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•.

๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„์›Œํฌ์˜ Suspense

React 18์—์„œ๋Š” Relay, Next.js, Hydrogen ๋˜๋Š” Remix์™€ ๊ฐ™์€ ๊ณ ์œ ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ์œ„ํ•ด Suspense๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Suspense๋ฅผ ์‚ฌ์šฉํ•œ Ad hoc ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋Š” ๊ธฐ์ˆ ์ ์œผ๋กœ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ผ๋ฐ˜์ ์ธ ์ „๋žต์œผ๋กœ ๊ถŒ์žฅ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

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

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

์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์•„์ง ๊ฐœ๋ฐœ ์ค‘์ž…๋‹ˆ๋‹ค.

์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ํด๋ผ์ด์–ธํŠธ ์ธก ์•ฑ์˜ ํ’๋ถ€ํ•œ ์ƒํ˜ธ์ž‘์šฉ๊ณผ ๊ธฐ์กด ์„œ๋ฒ„ ๋ Œ๋”๋ง์˜ ํ–ฅ์ƒ๋œ ์„ฑ๋Šฅ์„ ๊ฒฐํ•ฉํ•˜์—ฌ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ์•„์šฐ๋ฅด๋Š” ์•ฑ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ณง ์ถœ์‹œ๋  ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ณธ์งˆ์ ์œผ๋กœ Concurrent React์™€ ๊ฒฐํ•ฉํ•˜์—ฌ ์žˆ์ง€๋Š” ์•Š์ง€๋งŒ, Suspense ๋ฐ ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง๊ณผ ๊ฐ™์€ concurrent ๊ธฐ๋Šฅ์— ๊ฐ€์žฅ ์ž˜ ์ž‘๋™ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์•„์ง ์‹คํ—˜ ๋‹จ๊ณ„์ด์ง€๋งŒ 18.x ๋งˆ์ด๋„ˆ ๋ฆด๋ฆฌ์Šค์—์„œ ์ดˆ๊ธฐ ๋ฒ„์ „์„ ์ถœ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๊ทธ๋™์•ˆ์—๋Š” ์ด ์ œ์•ˆ์„ ๋ฐœ์ „์‹œํ‚ค๊ณ  ๊ด‘๋ฒ”์œ„ํ•œ ์ฑ„ํƒ์„ ์ค€๋น„ํ•˜๊ธฐ ์œ„ํ•ด Next.js, Hydrogen, Remix์™€ ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ํ˜‘๋ ฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ

์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ: ์ž๋™ Batching

Batching์€ React๊ฐ€ ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด ์—ฌ๋Ÿฌ state ์—…๋ฐ์ดํŠธ๋ฅผ ํ•˜๋‚˜์˜ ๋ฆฌ๋ Œ๋”๋ง์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž๋™ batching์ด ์—†์œผ๋ฉด ์šฐ๋ฆฌ๋Š” React ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋‚ด๋ถ€์˜ ์—…๋ฐ์ดํŠธ๋งŒ batch ํ–ˆ์Šต๋‹ˆ๋‹ค. Promises, setTimeout, ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๊ธฐํƒ€ ์ด๋ฒคํŠธ ๋‚ด๋ถ€์˜ ์—…๋ฐ์ดํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ React์—์„œ batch ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ž๋™ Batching์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฌํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์ž๋™์œผ๋กœ batch ๋ฉ๋‹ˆ๋‹ค.

// ๋ณ€๊ฒฝ ์ „: ์˜ค์ง React ์ด๋ฒคํŠธ๋งŒ batch ๋ฉ๋‹ˆ๋‹ค.
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React๋Š” ๊ฐ state ์—…๋ฐ์ดํŠธ๋งˆ๋‹ค ํ•œ ๋ฒˆ์”ฉ, ์ด ๋‘ ๋ฒˆ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. (batching ์•„๋‹˜)
}, 1000);

// ๋ณ€๊ฒฝ ํ›„: timeouts, promises ๋‚ด์—์„œ๋„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
// ๋„ค์ดํ‹ฐ๋ธŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋˜๋Š” ๋‹ค๋ฅธ ์ด๋ฒคํŠธ๋“ค์ด batch ๋ฉ๋‹ˆ๋‹ค.
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React๋Š” ๋งˆ์ง€๋ง‰์— ํ•œ ๋ฒˆ๋งŒ ๋‹ค์‹œ ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. (batching!)
}, 1000);

๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ Automatic batching for fewer renders in React 18์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ: Transitions

Transition์€ ๊ธด๊ธ‰ ์—…๋ฐ์ดํŠธ์™€ ๋น„๊ธด๊ธ‰ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•œ React์˜ ์ƒˆ๋กœ์šด ๊ฐœ๋…์ž…๋‹ˆ๋‹ค.

  • ๊ธด๊ธ‰ ์—…๋ฐ์ดํŠธ๋Š” ์ž…๋ ฅ, ํด๋ฆญ, ๋ˆ„๋ฅด๊ธฐ ๋“ฑ๊ณผ ๊ฐ™์€ ์ง์ ‘์ ์ธ ์ƒํ˜ธ์ž‘์šฉ์„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.
  • Transition ์—…๋ฐ์ดํŠธ๋Š” UI๋ฅผ ํ•œ ํ™”๋ฉด์—์„œ ๋‹ค๋ฅธ ํ™”๋ฉด์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์ž…๋ ฅ, ํด๋ฆญ, ๋ˆ„๋ฅด๊ธฐ ๋“ฑ์˜ ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ๋Š” ์‹ค์ œ ์‚ฌ๋ฌผ์˜ ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์šฐ๋ฆฌ์˜ ์ง๊ด€๊ณผ ์ผ์น˜ํ•˜๋„๋ก ์ฆ‰๊ฐ์ ์ธ ๋ฐ˜์‘์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด โ€œ์ž˜๋ชป๋๋‹คโ€๊ณ  ๋Š๋ผ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ transition์€ ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์— ๋ชจ๋“  ์ค‘๊ฐ„๊ฐ’์„ ๋ณผ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋“œ๋กญ๋‹ค์šด์—์„œ ํ•„ํ„ฐ๋ฅผ ์„ ํƒํ•˜๋ฉด ํด๋ฆญ ์ฆ‰์‹œ ํ•„ํ„ฐ ๋ฒ„ํŠผ ์ž์ฒด๊ฐ€ ๋ฐ˜์‘ํ•  ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ๊ฒฐ๊ณผ๋Š” ๋ณ„๋„๋กœ ์ „ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฝ๊ฐ„์˜ ์ง€์—ฐ์€ ๋ˆˆ์— ๋„์ง€ ์•Š๊ณ  ์ข…์ข… ์˜ˆ์ƒ๋˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋ Œ๋”๋ง ๋˜๊ธฐ ์ „์— ํ•„ํ„ฐ๋ฅผ ๋‹ค์‹œ ๋ณ€๊ฒฝํ•˜๋ฉด ์˜ค์ง ์ตœ์‹  ๊ฒฐ๊ณผ๋งŒ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์ตœ์ƒ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์œ„ํ•ด์„œ๋Š” ํ•œ ๋ฒˆ์˜ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์œผ๋กœ ๊ธด๊ธ‰ํ•œ ์—…๋ฐ์ดํŠธ์™€ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ชจ๋‘ ์ด๋ฃจ์–ด์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ ์ด๋ฒคํŠธ ๋‚ด์—์„œ startTransition API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ด๋–ค ์—…๋ฐ์ดํŠธ๊ฐ€ ๊ธด๊ธ‰ํ•œ์ง€, ์–ด๋–ค ์—…๋ฐ์ดํŠธ๊ฐ€ โ€œtransitionโ€์ธ์ง€ React์— ์•Œ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import { startTransition } from 'react';

// ๊ธด๊ธ‰: Urgent: ์ž…๋ ฅํ•œ ๋‚ด์šฉ ํ‘œ์‹œ
setInputValue(input);

// ๋‚ด๋ถ€์˜ ๋ชจ๋“  state ์—…๋ฐ์ดํŠธ๋ฅผ transition์œผ๋กœ ํ‘œ์‹œ
startTransition(() => {
// Transition: ๊ฒฐ๊ณผ ํ‘œ์‹œ
setSearchQuery(input);
});

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

  • useTransition: ๋ณด๋ฅ˜ ์ค‘์ธ(pending) state๋ฅผ ์ถ”์ ํ•˜๋Š” ๊ฐ’์„ ํฌํ•จํ•˜์—ฌ transition์„ ์‹œ์ž‘ํ•˜๋Š” Hook.
  • startTransition: Hook์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์„ ๋•Œ transition์„ ์‹œ์ž‘ํ•˜๋Š” ๋ฉ”์„œ๋“œ.

transition์€ concurrent ๋ Œ๋”๋ง์„ ์„ ํƒํ•˜์—ฌ ์—…๋ฐ์ดํŠธ๋ฅผ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ˜ํ…์ธ ๊ฐ€ ๋‹ค์‹œ ์ผ์‹œ ์ค‘๋‹จ๋˜๋ฉด, transition์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ transition ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ ํ˜„์žฌ ์ฝ˜ํ…์ธ ๋ฅผ ๊ณ„์† ํ‘œ์‹œํ•˜๋„๋ก React์— ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. (์ž์„ธํ•œ ๋‚ด์šฉ์€ Suspense RFC๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.)

Transitions ์ฐธ๊ณ  ๋ฌธ์„œ

์ƒˆ๋กœ์šด Suspense ๊ธฐ๋Šฅ๋“ค

Suspense๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์˜ ์ผ๋ถ€๊ฐ€ ์•„์ง ํ‘œ์‹œ๋  ์ค€๋น„๊ฐ€ ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋กœ๋”ฉ state๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>

Suspense๋Š” โ€œUI ๋กœ๋”ฉ ์ƒํƒœโ€๋ฅผ React ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ชจ๋ธ์—์„œ 1๊ธ‰ ์„ ์–ธ์  ๊ฐœ๋…์œผ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ทธ ์œ„์— ๋” ๋†’์€ ์ˆ˜์ค€์˜ ๊ธฐ๋Šฅ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋ช‡ ๋…„ ์ „์— Suspense์˜ ์ œํ•œ๋œ ๋ฒ„์ „์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ง€์›๋˜๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” React.lazy๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ ๋ถ„ํ• ๋ฟ์ด์—ˆ์œผ๋ฉฐ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋งํ•  ๋•Œ๋Š” ์ „ํ˜€ ์ง€์›๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

React 18์—์„œ๋Š” ์„œ๋ฒ„์—์„œ Suspense์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ•˜๊ณ  concurrent ๋ Œ๋”๋ง ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ–ˆ์Šต๋‹ˆ๋‹ค.

React 18์˜ Suspense๋Š” transition API์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ€์žฅ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. transition ๋„์ค‘ ์ผ์‹œ ์ค‘๋‹จํ•˜๋ฉด, React๋Š” ์ด๋ฏธ ํ‘œ์‹œ๋œ ์ฝ˜ํ…์ธ ๊ฐ€ fallback์œผ๋กœ ๋Œ€์ฒด๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹  React๋Š” ์ถฉ๋ถ„ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋“œ๋  ๋•Œ๊นŒ์ง€ ๋ Œ๋”๋ง์„ ์ง€์—ฐ์‹œ์ผœ ๋กœ๋”ฉ ์ƒํƒœ๊ฐ€ ๋‚˜๋น ์ง€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

Suspense in React 18 ์ฐธ๊ณ  ๋ฌธ์„œ

์ƒˆ๋กœ์šด ํด๋ผ์ด์–ธํŠธ ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋ง API๋“ค

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

React DOM ํด๋ผ์ด์–ธํŠธ

์ด ์ƒˆ๋กœ์šด API๋Š” ์ด์ œ react-dom/client์—์„œ ๋‚ด๋ณด๋‚ด์ง‘๋‹ˆ๋‹ค.

  • createRoot: ๋ Œ๋”๋ง ๋˜๋Š” unmount์— ๋ฃจํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ. ReactDOM.render ๋Œ€์‹  ์‚ฌ์šฉํ•˜์„ธ์š”. ์ด ํ•จ์ˆ˜๊ฐ€ ์—†์œผ๋ฉด React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ๋“ค์ด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • hydrateRoot: ์„œ๋ฒ„ ๋ Œ๋”๋ง๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ hydrateํ•˜๋Š” ์ƒˆ๋กœ์šด ๋ฉ”์„œ๋“œ. ์ƒˆ๋กœ์šด React DOM ์„œ๋ฒ„ API์™€ ํ•จ๊ป˜ ReactDOM.hydrate ๋Œ€์‹  ์‚ฌ์šฉํ•˜์„ธ์š”. ์ด ๋ฉ”์„œ๋“œ๊ฐ€ ์—†์œผ๋ฉด React 18์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

createRoot์™€ hydrateRoot๋Š” ๋ชจ๋‘ ๋ Œ๋”๋ง ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ๋กœ๊น…์„ ์œ„ํ•œ hydration ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์•Œ๋ฆผ์„ ๋ฐ›๊ณ ์ž ํ•˜๋Š” ๊ฒฝ์šฐ onRecoverableError๋ผ๋Š” ์ƒˆ๋กœ์šด ์˜ต์…˜์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ React๋Š” reportError ๋˜๋Š” ์˜ค๋ž˜๋œ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” console.error๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

React DOM ํด๋ผ์ด์–ธํŠธ ์ฐธ๊ณ  ๋ฌธ์„œ

React DOM ์„œ๋ฒ„

์ด ์ƒˆ๋กœ์šด API๋Š” ์ด์ œ react-dom/server์—์„œ ๋‚ด๋ณด๋‚ด์ง€๋ฉฐ ์„œ๋ฒ„์—์„œ Suspense๋ฅผ ์ŠคํŠธ๋ฆฌ๋ฐํ•˜๋Š” ๋ฐ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›๋ฉ๋‹ˆ๋‹ค.

  • renderToPipeableStream: Node ํ™˜๊ฒฝ์—์„œ์˜ ์ŠคํŠธ๋ฆฌ๋ฐ์šฉ.
  • renderToReadableStream: ์ตœ์‹  ์—ฃ์ง€ ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ(์˜ˆ: Deno ๋ฐ Cloudflare ์›Œ์ปค)์—์„œ์˜ ์ŠคํŠธ๋ฆฌ๋ฐ์šฉ.

๊ธฐ์กด์˜ renderToString ๋ฉ”์„œ๋“œ๋Š” ๊ณ„์† ์ž‘๋™ํ•˜์ง€๋งŒ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

React DOM ์„œ๋ฒ„ ์ฐธ๊ณ  ๋ฌธ์„œ

์ƒˆ๋กœ์šด Strict ๋ชจ๋“œ ๋™์ž‘๋“ค

์•ž์œผ๋กœ๋Š” ๋ฆฌ์•กํŠธ๊ฐ€ state๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ UI์˜ ์„น์…˜์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์—์„œ ๋ฒ—์–ด๋‚˜ ๋’ค๋กœ ํƒญ ํ•  ๋•Œ React๋Š” ์ด์ „ ํ™”๋ฉด์„ ์ฆ‰์‹œ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ๋ฆฌ์•กํŠธ๋Š” ์ด์ „๊ณผ ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ state๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋ฆฌ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ฉด React ์•ฑ์˜ ์„ฑ๋Šฅ์ด ์ฆ‰์‹œ ํ–ฅ์ƒ๋˜์ง€๋งŒ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ effect๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ ๋งˆ์šดํŠธ ๋ฐ ์†Œ๋ฉธํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ํƒ„๋ ฅ์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ effect๋Š” ๋ณ€๊ฒฝ ์—†์ด ์ž‘๋™ํ•˜์ง€๋งŒ ์ผ๋ถ€ effect๋Š” ํ•œ ๋ฒˆ๋งŒ ๋งˆ์šดํŠธ๋˜๊ฑฐ๋‚˜ ์†Œ๋ฉธํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด React 18์€ Strict ๋ชจ๋“œ์— ์ƒˆ๋กœ์šด ๊ฐœ๋ฐœ ์ „์šฉ ๊ฒ€์‚ฌ๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ์ƒˆ๋กœ์šด ๊ฒ€์‚ฌ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ฒ˜์Œ ๋งˆ์šดํŠธ๋  ๋•Œ๋งˆ๋‹ค ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž๋™์œผ๋กœ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•˜์—ฌ ๋‘ ๋ฒˆ์งธ ๋งˆ์šดํŠธ ์‹œ ์ด์ „ state๋กœ ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ณ€๊ฒฝ ์ „์—๋Š” React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•˜๊ณ  effect๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

* React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค.
* ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
* Effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

React 18์˜ Strict ๋ชจ๋“œ์—์„œ๋Š” ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธ ํ•ด์ œํ•˜๊ณ  ๋‹ค์‹œ ๋งˆ์šดํŠธํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค.

* React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค.
* ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
* Effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
* React๊ฐ€ ์ปดํฌ๋„ŒํŠธ ๋งˆ์šดํŠธ ํ•ด์ œ๋ฅผ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค.
* ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์†Œ๋ฉธํ•ฉ๋‹ˆ๋‹ค.
* Effect๊ฐ€ ์†Œ๋ฉธํ•ฉ๋‹ˆ๋‹ค.
* React๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ด์ „ ์ƒํƒœ๋กœ ๋งˆ์šดํŠธํ•˜๋Š” ๊ฒƒ์„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ฉ๋‹ˆ๋‹ค.
* ๋ ˆ์ด์•„์›ƒ effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
* Effect๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” state ๋ณด์žฅ์— ๋Œ€ํ•œ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์ƒˆ๋กœ์šด Hooks

useId

useId๋Š” hydration ๋ถˆ์ผ์น˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋ฉด์„œ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๋ชจ๋‘์—์„œ ๊ณ ์œ  ID๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ๊ณ ์œ  ID๊ฐ€ ํ•„์š”ํ•œ ์ ‘๊ทผ์„ฑ API์™€ ํ†ตํ•ฉ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” React 17 ์ดํ•˜์—์„œ ์ด๋ฏธ ์กด์žฌํ•˜๋˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋งŒ, ์ƒˆ๋กœ์šด ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋ฒ„ ๋ Œ๋”๋Ÿฌ๊ฐ€ HTML์„ ์ˆœ์„œ๋Œ€๋กœ ์ „๋‹ฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— React 18์—์„œ๋Š” ๋”์šฑ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ  ๋ฌธ์„œ

์ฃผ์˜

useId๋Š” ๋ชฉ๋ก์—์„œ key๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. Key๋Š” ์—ฌ๋Ÿฌ๋ถ„์˜ ๋ฐ์ดํ„ฐ์—์„œ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

useTransition

useTransition๊ณผ startTransition์œผ๋กœ ์ผ๋ถ€ state ์—…๋ฐ์ดํŠธ๋ฅผ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ state ์—…๋ฐ์ดํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ธด๊ธ‰ํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค. React๋Š” ๊ธด๊ธ‰ํ•œ state ์—…๋ฐ์ดํŠธ(์˜ˆ: ํ…์ŠคํŠธ input ์—…๋ฐ์ดํŠธ)๊ฐ€ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ state ์—…๋ฐ์ดํŠธ(์˜ˆ: ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋ชฉ๋ก ๋ Œ๋”๋ง)๋ฅผ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ  ๋ฌธ์„œ

useDeferredValue

useDeferredValue๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŠธ๋ฆฌ์—์„œ ๊ธด๊ธ‰ํ•˜์ง€ ์•Š์€ ๋ถ€๋ถ„์˜ ๋ฆฌ๋ Œ๋”๋ง์„ ์ง€์—ฐ(deferred)์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋””๋ฐ”์šด์‹ฑ๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ ๋””๋ฐ”์šด์‹ฑ์— ๋น„ํ•ด ๋ช‡ ๊ฐ€์ง€ ์žฅ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณ ์ •๋œ ์‹œ๊ฐ„ ์ง€์—ฐ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— React๋Š” ์ฒซ ๋ฒˆ์งธ ๋ Œ๋”๋ง์ด ํ™”๋ฉด์— ๋ฐ˜์˜๋œ ์งํ›„์— deferred ๋ Œ๋”๋ง์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. deferred ๋ Œ๋”๋ง์€ ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์„ ์ฐจ๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ  ๋ฌธ์„œ

useSyncExternalStore

useSyncExternalStore๋Š” ์Šคํ† ์–ด์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ฐ•์ œ๋กœ ๋™๊ธฐํ™”ํ•˜์—ฌ ์™ธ๋ถ€ ์Šคํ† ์–ด๊ฐ€ ๋™์‹œ ์ฝ๊ธฐ๋ฅผ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ด Hook์€ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๊ตฌ๋…์„ ๊ตฌํ˜„ํ•  ๋•Œ useEffect๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฉฐ, React ์™ธ๋ถ€ state์™€ ํ†ตํ•ฉํ•˜๋Š” ๋ชจ๋“  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ  ๋ฌธ์„œ

์ฃผ์˜

useSyncExternalStore๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

useInsertionEffect

useInsertionEffect๋Š” CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋ Œ๋”๋ง์—์„œ ์Šคํƒ€์ผ์„ ์‚ฝ์ž…ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด Hook์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ CSS-in-JS ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์ด Hook์„ ์‚ฌ์šฉํ•  ์ผ์€ ์—†์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค. ์ด Hook์€ DOM์ด ๋ณ€๊ฒฝ๋œ ํ›„์— ์‹คํ–‰๋˜์ง€๋งŒ, ๋ ˆ์ด์•„์›ƒ effects๊ฐ€ ์ƒˆ ๋ ˆ์ด์•„์›ƒ์„ ์ฝ๊ธฐ ์ „์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” React 17 ์ดํ•˜์—์„œ ์ด๋ฏธ ์กด์žฌํ•˜๋˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€๋งŒ, React 18์—์„œ๋Š” concurrent ๋ Œ๋”๋ง ์ค‘์— ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ ˆ์ด์•„์›ƒ์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•  ๊ธฐํšŒ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋”์šฑ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ฐธ๊ณ  ๋ฌธ์„œ

์ฃผ์˜

useInsertionEffect ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•

๋‹จ๊ณ„๋ณ„ ์ง€์นจ๊ณผ ์ฃผ์š” ์ฃผ๋ชฉํ•  ๋งŒํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๋ชฉ๋ก์€ React 18๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

Changelog

React

React DOM

React DOM Server

React DOM Test Utils

  • Throw when act is used in production. (#21686 by @acdlite)
  • Support disabling spurious act warnings with global.IS_REACT_ACT_ENVIRONMENT. (#22561 by @acdlite)
  • Expand act warning to cover all APIs that might schedule React work. (#22607 by @acdlite)
  • Make act batch updates. (#21797 by @acdlite)
  • Remove warning for dangling passive effects. (#22609 by @acdlite)

React Refresh

Server Components (Experimental)