React v18.0
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์์ ๋ง์ ๋ถ๋ถ์ ๊ณต์ ํ์ต๋๋ค.
- ์ด ์ฐ์ค์์๋ ๊ฐ๋ฐ์๋ค์ด ํ๋ฅญํ ์ฌ์ฉ์ ๊ฒฝํ์ ์ฝ๊ฒ ๊ตฌ์ถํ ์ ์๋๋ก ๋๋ ์ฐ๋ฆฌ์ ์๋ฌด์ React 18์ด ์ด๋ป๊ฒ ๋ถํฉํ๋์ง ์ค๋ช ํ์ต๋๋ค.
- Shruti Kapoor๊ฐ React 18์ ์๋ก์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์ฐํ์ต๋๋ค.
- Shaundai Person์ด Suspense๋ฅผ ์ฌ์ฉํ ์คํธ๋ฆฌ๋ฐ ์๋ฒ ๋ ๋๋ง์ ๋ํ ๊ฐ์๋ฅผ ์ค๋ช ํ์ต๋๋ค.
๋ค์์ Concurrent ๋ ๋๋ง๋ถํฐ ์์ํ์ฌ ์ด๋ฒ ๋ฆด๋ฆฌ์ค์์ ๊ธฐ๋ํ ์ ์๋ ๊ธฐ๋ฅ์ ๋ํ ์ ์ฒด ๊ฐ์์ ๋๋ค.
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๋ฅผ ์ฐธ๊ณ ํ์ธ์.)
์๋ก์ด 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 ๋ฉ์๋๋ ๊ณ์ ์๋ํ์ง๋ง ๊ถ์ฅํ์ง ์์ต๋๋ค.
์๋ก์ด 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
- Add
useTransitionanduseDeferredValueto separate urgent updates from transitions. (#10426, #10715, #15593, #15272, #15578, #15769, #17058, #18796, #19121, #19703, #19719, #19724, #20672, #20976 by @acdlite, @lunaruan, @rickhanlonii, and @sebmarkbage) - Add
useIdfor generating unique IDs. (#17322, #18576, #22644, #22672, #21260 by @acdlite, @lunaruan, and @sebmarkbage) - Add
useSyncExternalStoreto help external store libraries integrate with React. (#15022, #18000, #18771, #22211, #22292, #22239, #22347, #23150 by @acdlite, @bvaughn, and @drarmstr) - Add
startTransitionas a version ofuseTransitionwithout pending feedback. (#19696 by @rickhanlonii) - Add
useInsertionEffectfor CSS-in-JS libraries. (#21913 by @rickhanlonii) - Make Suspense remount layout effects when content reappears. (#19322, #19374, #19523, #20625, #21079 by @acdlite, @bvaughn, and @lunaruan)
- Make
<StrictMode>re-run effects to check for restorable state. (#19523 , #21418 by @bvaughn and @lunaruan) - Assume Symbols are always available. (#23348 by @sebmarkbage)
- Remove
object-assignpolyfill. (#23351 by @sebmarkbage) - Remove unsupported
unstable_changedBitsAPI. (#20953 by @acdlite) - Allow components to render undefined. (#21869 by @rickhanlonii)
- Flush
useEffectresulting from discrete events like clicks synchronously. (#21150 by @acdlite) - Suspense
fallback={undefined}now behaves the same asnulland isnโt ignored. (#21854 by @rickhanlonii) - Consider all
lazy()resolving to the same component equivalent. (#20357 by @sebmarkbage) - Donโt patch console during first render. (#22308 by @lunaruan)
- Improve memory usage. (#21039 by @bgirard)
- Improve messages if string coercion throws (Temporal.*, Symbol, etc.) (#22064 by @justingrant)
- Use
setImmediatewhen available overMessageChannel. (#20834 by @gaearon) - Fix context failing to propagate inside suspended trees. (#23095 by @gaearon)
- Fix
useReducerobserving incorrect props by removing the eager bailout mechanism. (#22445 by @josephsavona) - Fix
setStatebeing ignored in Safari when appending iframes. (#23111 by @gaearon) - Fix a crash when rendering
ZonedDateTimein the tree. (#20617 by @dimaqq) - Fix a crash when document is set to
nullin tests. (#22695 by @SimenB) - Fix
onLoadnot triggering when concurrent features are on. (#23316 by @gnoff) - Fix a warning when a selector returns
NaN. (#23333 by @hachibeeDI) - Fix a crash when document is set to
nullin tests. (#22695 by @SimenB) - Fix the generated license header. (#23004 by @vitaliemiron)
- Add
package.jsonas one of the entry points. (#22954 by @Jack) - Allow suspending outside a Suspense boundary. (#23267 by @acdlite)
- Log a recoverable error whenever hydration fails. (#23319 by @acdlite)
React DOM
- Add
createRootandhydrateRoot. (#10239, #11225, #12117, #13732, #15502, #15532, #17035, #17165, #20669, #20748, #20888, #21072, #21417, #21652, #21687, #23207, #23385 by @acdlite, @bvaughn, @gaearon, @lunaruan, @rickhanlonii, @trueadm, and @sebmarkbage) - Add selective hydration. (#14717, #14884, #16725, #16880, #17004, #22416, #22629, #22448, #22856, #23176 by @acdlite, @gaearon, @salazarm, and @sebmarkbage)
- Add
aria-descriptionto the list of known ARIA attributes. (#22142 by @mahyareb) - Add
onResizeevent to video elements. (#21973 by @rileyjshaw) - Add
imageSizesandimageSrcSetto known props. (#22550 by @eps1lon) - Allow non-string
<option>children ifvalueis provided. (#21431 by @sebmarkbage) - Fix
aspectRatiostyle not being applied. (#21100 by @gaearon) - Warn if
renderSubtreeIntoContaineris called. (#23355 by @acdlite)
React DOM Server
- Add the new streaming renderer. (#14144, #20970, #21056, #21255, #21200, #21257, #21276, #22443, #22450, #23247, #24025, #24030 by @sebmarkbage)
- Fix context providers in SSR when handling multiple requests. (#23171 by @frandiox)
- Revert to client render on text mismatch. (#23354 by @acdlite)
- Deprecate
renderToNodeStream. (#23359 by @sebmarkbage) - Fix a spurious error log in the new server renderer. (#24043 by @eps1lon)
- Fix a bug in the new server renderer. (#22617 by @shuding)
- Ignore function and symbol values inside custom elements on the server. (#21157 by @sebmarkbage)
React DOM Test Utils
- Throw when
actis 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
actbatch updates. (#21797 by @acdlite) - Remove warning for dangling passive effects. (#22609 by @acdlite)
React Refresh
- Track late-mounted roots in Fast Refresh. (#22740 by @anc95)
- Add
exportsfield topackage.json. (#23087 by @otakustay)