componentWillMount๊ฐ ์ฝ์์ ๋ฐํํ ์ ์๊ณ ํด๋น ๋ฐ์์ด ํด๋น ์ฝ์์ด ํด๊ฒฐ๋ ๋๊น์ง ๋ ๋๋ง์ ์ง์ฐํ๋ค๋ฉด ๋ํ์ ๊ตฌ์ถํ๋ ํ๋ก์ธ์ค๋ฅผ ์ฌ๊ฐํ๊ฒ ์์ํ๊ฒ ๋ง๋ค ๊ฒ์ ๋๋ค. react-router ๋ฐ rrouter์์ ์ด์ ๊ฐ์ ์์ ์ ์ํํ๋ ค๋ ์๋๋ฅผ ๋ณด์์ง๋ง ๋ผ์ฐํฐ ๋ชจ๋ ๋์ ๊ฐ ๊ตฌ์ฑ ์์์ ์ด ์ฑ ์์ ๋ถ์ฌํ๋ ๊ฒ์ด ๋ ํฉ๋ฆฌ์ ์ ๋๋ค.
์ด๊ฒ์ด ์ด๋ฏธ ์กด์ฌํ์ง ์๋ ์ฃผ๋ ์ด์ (๋ด ์๊ฐ์)๋ ํด๋ผ์ด์ธํธ ์ธก์์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ ๋๋ง์ ์ฐ๊ธฐํ๋ ๋์ ํญ์ ์ผ์ข ์ ๋ก๋ ํ์๊ธฐ๋ฅผ ํ์ํ๊ธฐ๋ฅผ ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. (๊ทธ๊ฒ์ ๋ํ ์ฝ๋๋ฅผ ํจ์ฌ ๋ ๋ณต์กํ๊ฒ ๋ง๋ค์ง๋ง ์๋ง๋ ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ค๋ฃฐ ์ ์์ ๊ฒ์ ๋๋ค.)
๊ทธ๊ฒ ์์ด๋ ํด๊ฒฐํ๊ธฐ ์ด๋ ค์ด ๋ ๊ฐ์ง ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.
react-async ๋ ํ์ด๋ฒ ๋ฐ ์บ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค. ๊ทธ๊ฒ์ ํธ๋ฆญ์ ์ํํ์ง๋ง ๋ด ๊ด์ ์์ ๊ทธ๊ฒ๋ค์ ํต์ฌ์์๋ง ํด๊ฒฐํ ์ ์๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ _hackish_ ์๋ฃจ์ ์ ๋๋ค.
@fdecampredon ์ ์ด ์ฃผ์ ์ ๋ํด ์์ง componentWillMount
๊ฐ ๋น๋๊ธฐ์์ด๊ณ ์๋ฌด ๊ฒ๋ ์ฆ์ ๋ฐํํ์ง ์๋๋ค๊ณ ๋งํฉ๋๋ค. ์๋ฌด๊ฒ๋ ์์ ๋๊น์ง React๋ ๋ฌด์์ ๋ ๋๋งํด์ผ ํฉ๋๊น? ๊ทธ๋ ๋ค๋ฉด ์์ง ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ ๋ ๋๋ง์์ ์๋ฌด ๊ฒ๋ ๋ฐํํ์ง ์๋ ์ด์ ๋ ๋ฌด์์
๋๊น? (์, ์๋ฒ ์ธก์ ์ป์ต๋๋ค) ๋ํ componentWillMount
๊ฐ ์คํ๋๊ธฐ ์ ์ props๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ด๋ป๊ฒ ๋ฉ๋๊น?
๊ฐ์ธ์ ์ผ๋ก ์ปดํฌ๋ํธ๊ฐ ์ค์ ๋ก ๊ฒฉ๋ฆฌ๋ ๋ธ๋๋ฐ์ค์ด๊ณ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ๊ตฌํํ์ง ์๋ ํ componentWillMount
๋์ ๋น๋๊ธฐ ์์ฒญ์ ๋ฐ์กํ๋ ๊ฒ์ ์๋ชป๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ด๊ฐ ์ดํดํ๋ ํ React ๊ตฌ์ฑ ์์๋ ๋ ์ผ๋ฐ์ ์ธ OOP ์ธ์คํด์ค๋ก ์ค์ธ๋์ด์๋ ์๋ฉ๋๋ค. ๊ฐ์ฅ ์ข์ ๊ฒฝ์ฐ React ๊ตฌ์ฑ ์์๋ props์ ๋ฐ์ดํฐ๋ฅผ ์๊ฐํํ๋ ๋๊ตฌ์
๋๋ค. ๋ํํ์ด๋ฉด state๋ ๊ฐ๋ฅํฉ๋๋ค. ๋ทฐ์ ๋ชจ๋ธ์ด ์๋๋ผ ๋ทฐ์
๋๋ค.
๋ด ๊ท์ ๊ทธ๊ฒ์ ๋ฌธ์ ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค. React ๊ตฌ์ฑ ์์๋ ๋น๋๊ธฐ ์์ฒญ์ ์ ๋ฌํ๋ ๊ตฌ์ฑ ์์๊ฐ ์๋์ด์ผ ํฉ๋๋ค. ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ํด๋น ๋ฐ์ดํฐ๊ฐ ์ค๋น๋๋ฉด React.renderComponent
ํธ์ถํด์ผ ํฉ๋๋ค. ๋์ผํ ์๋ฃจ์
ํด๋ผ์ด์ธํธ ์ธก ๋ฐ ์๋ฒ ์ธก. ๋น๋๊ธฐ ์์ฒญ์ด ์คํจํ ๊ฒฝ์ฐ ์ ํํ ๊ฒฐ๊ณผ๋ก ์ค๋จํ ์๋ ์์ต๋๋ค.
๋ด๊ฐ ์๋ชป ์ดํดํ ๊ฒ์ด ์์ผ๋ฉด ์ธ์ ๋ ์ง ์ ๋ฅผ ๋ฌด์ํด ์ฃผ์ธ์. ๊ทธ๋ฌ๋ React ๊ตฌ์ฑ ์์๋ฅผ ๋ณด๊ธฐ์ ๋ชจ๋ธ๋ก ์ทจ๊ธํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
@fdecampredon ์ componentWillMount๊ฐ ๋น๋๊ธฐ์ด๊ณ ์ฆ์ ์๋ฌด ๊ฒ๋ ๋ฐํํ์ง ์๋๋ค๊ณ ๋งํฉ๋๋ค. ์๋ฌด๊ฒ๋ ์์ ๋๊น์ง React๋ ๋ฌด์์ ๋ ๋๋งํด์ผ ํฉ๋๊น? ๊ทธ๋ ๋ค๋ฉด ์์ง ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ ๋ ๋๋ง์์ ์๋ฌด ๊ฒ๋ ๋ฐํํ์ง ์๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? (์, ์๋ฒ ์ธก์ ์ป์ต๋๋ค) ๋ํ componentWillMount๊ฐ ์คํ๋๊ธฐ ์ ์ props๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ด๋ป๊ฒ ๋ฉ๋๊น?
๋ชจ๋ ๊ฒฝ์ฐ์ ๋ํด ์๊ฐํ์ง ์์๋ค๋ ๊ฒ์ ์ธ์ ํด์ผํฉ๋๋ค ^^.
์ด ๊ธฐ๋ฅ์ ์ต์์ ๊ตฌ์ฑ ์์๋ฅผ ์ฒ์ ๋ง์ดํธํ ๋๋ง ์ ์ฉํ๋ฉฐ, ๊ทธ๋ ์ง ์์ผ๋ฉด ๋๋ถ๋ถ์ ์บ์คํธ์์ ๋ก๋ ํ์๊ธฐ๋ฅผ ํ์ํ๋ ค๋ ๊ฒ์ด ์ฌ์ค์
๋๋ค.
๊ฐ์ธ์ ์ผ๋ก ์ปดํฌ๋ํธ๊ฐ ์ค์ ๋ก ๊ฒฉ๋ฆฌ๋ ๋ธ๋๋ฐ์ค์ด๊ณ ๋ก๋ฉ ํ์๊ธฐ๋ฅผ ๊ตฌํํ์ง ์๋ ํ componentWillMount ์ค์ ๋น๋๊ธฐ ์์ฒญ์ ์ ๋ฌํ๋ ๊ฒ์ ์๋ชป๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ด๊ฐ ์ดํดํ๋ ํ React ๊ตฌ์ฑ ์์๋ ๋ ์ผ๋ฐ์ ์ธ OOP ์ธ์คํด์ค๋ก ์ค์ธ๋์ด์๋ ์๋ฉ๋๋ค. ๊ฐ์ฅ ์ข์ ๊ฒฝ์ฐ React ๊ตฌ์ฑ ์์๋ props์ ๋ฐ์ดํฐ๋ฅผ ์๊ฐํํ๋ ๋๊ตฌ์ ๋๋ค. ๋ํํ์ด๋ฉด state๋ ๊ฐ๋ฅํฉ๋๋ค. ๋ทฐ์ ๋ชจ๋ธ์ด ์๋๋ผ ๋ทฐ์ ๋๋ค.
์ด๋ค ์์ผ๋ก๋ Flux ์ํ ์์ ์ํ๋ ๊ฒ์ฒ๋ผ '์ต์์' ๊ตฌ์ฑ ์์๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํ ์ ์๊ธฐ๋ฅผ ์ํ ๊ฒ์
๋๋ค.
์ด ์ํ์์๋ ํ ์ผ ๋ชฉ๋ก์ ๊ฒ์ํ๋ ๊ฒ์ด ๋๊ธฐ์ ์์
์ด๊ธฐ ๋๋ฌธ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ์๋ ์๋ฒ์์ ์ฌ์ ๋ ๋๋งํ๋ ๊ฒฝ์ฐ ๋ฐ์ดํฐ ์์ด ์ฒ์์ผ๋ก ๋ ๋๋งํฉ๋๋ค(๊ทธ๋ฆฌ๊ณ ์ฌ์ ๋ ๋๋ง๋ ์๋ฒ์์ ๋งํฌ์
).
ํ๋์ ๋ทฐ ๊ณ์ธต ๊ตฌ์กฐ์ ์ํด ํ์๋๋ ํ๋์ ๋ฐ์ดํฐ ์ธํธ๊ฐ ์๋ ๊ฐ๋จํ ์ ํ๋ฆฌ์ผ์ด์
์ ๊ฒฝ์ฐ ์ฌ์ ํ ๋ฌธ์ ๊ฐ ๋ง์ง ์์ต๋๋ค. ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ก๋ํ๊ณ ์ ์ฅ์์ ๋๊ธฐ ์์ฑ์ ๊ณ์ ์ ์งํ ์ ์์ต๋๋ค.
์ด์ ์์ฉ ํ๋ก๊ทธ๋จ ์ ์ฒด์์ ์ฌ์ฌ์ฉํ๋ ์ฌ๋ฌ ๋ชจ๋๋ก ๊ตฌ์ฑ๋ ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ฒฝ์ฐ ํด๋น ๋ชจ๋์ ๋ค๋ฅธ ์ ์ฅ์(๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋ด๋นํจ)์์ '๊ตฌ๋
'ํ ์ ์๋ ๋ณ๋์ ์์ฉ ํ๋ก๊ทธ๋จ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์๋ง๋ ๋ด๊ฐ ์๋ชป๋ ๋ฐฉ์์ผ๋ก ์ผ์ ์ดํดํ์ง๋ง ์น ์ฃผ๋ณ์ ์ผ๋ถ ํ ๋ก /์ํ๋ก ์ธํด ์ด๋๊ฐ์ ๋๋ฝ๋ ๊ฒ์ด ์๋ค๊ณ ์๊ฐํ๊ฒ ๋ ๊ฒ์ ๋๋ค.
willTransitionTo
์์ ์ ์ฌํ ๋ฉ์ปค๋์ฆ์ ํ๋ณดํ๊ณ ์ผ๋ถ ํ ๋ก ์์๋ ์๋ฌด๋ ์ ์ ํ ์๋ฃจ์
์ ์ฐพ์ง ๋ชปํ๋ค๊ณ ๋๋๋๋ค.@fdecampredon ๋ช
ํํ๊ฒ, react-nested-router์์ willTransitionTo
์ ๋ชฉ์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๊ธฐ ์ํ _์๋_์
๋๋ค. ํนํ ํด๋น ๋ฉ์๋์์ ์ฝ์์ ๋ฐํํ๋ฉด ์ค์ ๋ก ์ํ์ง ์๋ ์ UI ๋ ๋๋ง์ด ์ฐจ๋จ๋๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ผญ ํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ฉด.
@fdecampredon ๋ชจ๋๊ฐ ์ฌ์ ํ ๋ฌธ์ ๋ฅผ ํ์ ํ๋ ค๊ณ ๋ ธ๋ ฅํ๊ณ ์์ผ๋ฏ๋ก ์๋ฌด๋ ํ์คํ ๋ต์ ๊ฐ์ง๊ณ ์์ง ์์๋ ๋๋ผ์ง ์์ ๊ฒ์ ๋๋ค. ํ์ง๋ง Facebook์ ๊ฐ๋ฐ์๋ค์ ์ด ๋ฌธ์ ๋ฅผ ๋ช ๋ฒ ๊ฒช์์ ๊ฒ์ ๋๋ค.
์ด์ ๋ํ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น? ๋๋ ๋ง React๋ฅผ ํ์ํ๊ธฐ ์์ํ๊ณ ์ฆ์ ์ด๊ฒ์ ๋ถ๋ช์ณค์ต๋๋ค. ๋ง์ ์ฌ๋๋ค์ด ๋ํ ์ฑ์ ๋น๋ํ๊ธฐ ์ํ ์๋ฃจ์ ์ผ๋ก React๋ฅผ ์ถ์ฒํ์ง๋ง ์ด๊ฒ์ด ํด๊ฒฐ๋์ง ์๋ ํ ๋จ์ํ ์์ ์ ์๋ฃํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ด ๊ท์ ๊ทธ๊ฒ์ ๋ฌธ์ ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค. React ๊ตฌ์ฑ ์์๋ ๋น๋๊ธฐ ์์ฒญ์ ์ ๋ฌํ๋ ๊ตฌ์ฑ ์์๊ฐ ์๋์ด์ผ ํฉ๋๋ค. ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ํด๋น ๋ฐ์ดํฐ๊ฐ ์ค๋น๋๋ฉด React.renderComponent๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค. ๋์ผํ ์๋ฃจ์ ํด๋ผ์ด์ธํธ ์ธก ๋ฐ ์๋ฒ ์ธก. ๋น๋๊ธฐ ์์ฒญ์ด ์คํจํ ๊ฒฝ์ฐ ์ ํํ ๊ฒฐ๊ณผ๋ก ์ค๋จํ ์๋ ์์ต๋๋ค.
๋ด๊ฐ ์๋ชป ์ดํดํ ๊ฒ์ด ์์ผ๋ฉด ์ธ์ ๋ ์ง ์ ๋ฅผ ๋ฌด์ํด ์ฃผ์ธ์. ๊ทธ๋ฌ๋ React ๊ตฌ์ฑ ์์๋ฅผ ๋ณด๊ธฐ์ ๋ชจ๋ธ๋ก ์ทจ๊ธํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ด๊ฒ์ด ์ฌ์ค์ด๋ผ๋ฉด React๋ ์ฝ๊ฐ ๋ค๋ฅธ ํ ํ๋ฆฟ ์๋ฃจ์ /๋ทฐ ๋ ์ด์ด์ ๋ถ๊ณผํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ฌํ ๊ฐ๋ฅ์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ๋ถ๋๋ฌ์ด ์ผ์ ๋๋ค. @fdecampredon ์ด ์ฌ๋ฌ ๋ชจ๋๋ก ๊ตฌ์ฑ๋ ๋ณต์กํ ์์ฉ ํ๋ก๊ทธ๋จ์ ์ธ๊ธํ ๋ ์ ๋ง ์ดํดํฉ๋๋ค. React๋ ์ด๊ฒ์ ์ํด ์๋ฒฝํ ๊ฒ์ ๋๋ค.
์ด ์ ๊ทผ ๋ฐฉ์์ด ๊ตฌ์ฑ ์์๋ฅผ ๋ณด๊ธฐ ๋ฐ ๋ชจ๋ธ๋ก ์ทจ๊ธํ๋ ๊ฒ์ ์๋ฏธํ๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค. Flux ์ํคํ ์ฒ๋ฅผ ๋ณด๋ฉด React ๊ตฌ์ฑ ์์๋ฅผ _controller-views_๋ก ์๊ฐํฉ๋๋ค. ์ด ๊ตฌ์ฑ ์์๋ ๋ฐ์ดํฐ๋ฅผ ํ์ํ ๋ฟ๋ง ์๋๋ผ ์ฌ์ฉ์ ์ํธ ์์ฉ์ ๊ธฐ๋ฐ์ผ๋ก ์์ ์ ํธ์ถํ๋ _controller-views_์ ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์์ ์ ์์ (= ๋ชจ๋ธ)์ ์ ๋ฐ์ดํธํฉ๋๋ค. ๋์๊ฒ ๊ทธ๊ฒ์ ๋ช ๋ฐฑํ MVC ์ํคํ ์ฒ์ฒ๋ผ ๋ค๋ฆฝ๋๋ค.
๋ฌธ์ ๋ ์์ ์ ์ฑ์ฐ๋ ์ด๊ธฐ ์กฐ์น์ ์์ต๋๋ค. ํด๋ผ์ด์ธํธ ์ธก์์๋ ๊ถ์ฅํ๋ ๋๋ก componentDidMount()
๋ฉ์๋์์ ์์
์ ํธ์ถํ ์ ์๋ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ๋ฐ๋ฉด์ ์๋ฒ ์ธก์์๋ ์์
์ด ์๋ฃ๋๊ณ ์ ์ฅ์๊ฐ ์ฑ์์ง ๋๊น์ง ๋ ๋๋ง์ ์ง์ฐ์ํค๋ ํน๋ณํ ์ฅ์์ ์ผ์ข
์ ๋ฉ์ปค๋์ฆ์ด ์ ๋ง๋ก ํ์ํฉ๋๋ค.
ํ์ฌ๋ก์๋ React-async/Fibers + Flux๊ฐ ์ ์ผํ ๋ฐฉ๋ฒ์ธ ๊ฒ ๊ฐ์ต๋๋ค. Flux์ ์ข์ ์ ์ ๊ตฌ์ฑ ์์ ์ํ๋ฅผ ์๋ฒ์์ ํด๋ผ์ด์ธํธ๋ก ์ ์กํ๊ธฐ ์ํด ์ธ๊ณต ์บ์๊ฐ ํ์ํ์ง ์๋ค๋ ๊ฒ์ ๋๋ค(์๋ react-async ์์ ์์ ์ํํ ๊ฒ์ฒ๋ผ). ๊ฐ๋จํ ์ ์ฅ์๋ฅผ ์ด๊ธฐํํ ๋ค์ ์ ์ฅ์๋ก ๋ณด๋ผ ์ ์์ต๋๋ค. html ๋งํฌ์ ์ด ์๋ ํด๋ผ์ด์ธํธ( ์ด ์์ ์ฐธ์กฐ).
๊ทธ๋ฌ๋ ์ด ์๋ฃจ์ ์ ์ค์ ๋ก _hackish_์ ๋๋ค.
๋น๋๊ธฐ์์ธ componentWillMount๊ฐ ๋ฐ๋์ ํ์ํ๋ค๊ณ ์๊ฐํ์ง๋ ์์ต๋๋ค. ๋ผ์ดํ ์ฌ์ดํด ์ด๋ฒคํธ๊ฐ ํ์ํ์ง์กฐ์ฐจ ํ์คํ์ง ์์ต๋๋ค. ์ง์ง ๋ฌธ์ ๋ ์๋ฒ ์ธก์์ ๋ชจ๋ ๊ฒ์ด ๋ฌธ์์ด๋ก ๋ ๋๋ง๋ ๋๊น์ง ๊ตฌ์ฑ ์์ ํธ๋ฆฌ๋ฅผ ๋ถ์ํ ๋ฐฉ๋ฒ์ด ์๋ค๋ ๊ฒ์ ๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ด์์ ์ธ ์๋ฃจ์ ์ ๊ตฌ์ฑ ์์ ํธ๋ฆฌ๋ฅผ ๊ตฌ์ถํ๋ "๋ ๋๋ง"์ ํ์ฉํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ฉด ํธ๋ฆฌ๋ฅผ ํ์ํ์ฌ ์ถ๊ฐ ๋ฐ์ดํฐ๊ฐ ํ์ํ ๊ตฌ์ฑ ์์๋ฅผ ์ฐพ๊ณ ๋ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๋ก๋ํ๊ณ "๋ค์ ๋ ๋๋งํ ์ ์์ต๋๋ค. " ํด๋น ๊ตฌ์ฑ ์์ ํ์ ํธ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ ๋งํฌ์ ์ ํ๋ฌ์ํ ์ค๋น๊ฐ ๋๋ฉด ํด๋น ํธ๋ฆฌ๋ฅผ ๋ฌธ์์ด๋ก ๋ณํํ ์ ์์ต๋๋ค.
์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ๋ธ๋ผ์ฐ์ ์์ ํ ์ ์๋ ์ผ์ ๋ณต์ ํฉ๋๋ค: ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋๋ก ๋ค์ ๋ ๋๋งํ ์ ์๋ ๊ฐ์ DOM์ด ์์ต๋๋ค. ์ฐจ์ด์ ์ ๋ธ๋ผ์ฐ์ ์์ DOM ์ ๋ฐ์ดํธ๊ฐ ์์์ ์ผ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์๋ฒ์์๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ์ DOM์ ๋ํ ์ ๋ฐ์ดํธ๋ฅผ ์ํํ ์ ์๋๋ก ๋ฌธ์์ด๋ก ๋ ๋๋งํ๋ ์๊ธฐ์ ๋ํด ๋ช ์์ ์ด์ด์ผ ํฉ๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ด์์ ์ธ ์๋ฃจ์ ์ ๊ตฌ์ฑ ์์ ํธ๋ฆฌ๋ฅผ ๊ตฌ์ถํ๋ "๋ ๋๋ง"์ ํ์ฉํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ฉด ํธ๋ฆฌ๋ฅผ ํ์ํ์ฌ ์ถ๊ฐ ๋ฐ์ดํฐ๊ฐ ํ์ํ ๊ตฌ์ฑ ์์๋ฅผ ์ฐพ๊ณ ๋ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๋ก๋ํ๊ณ "๋ค์ ๋ ๋๋งํ ์ ์์ต๋๋ค. " ํด๋น ๊ตฌ์ฑ ์์ ํ์ ํธ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ ๋งํฌ์ ์ ํ๋ฌ์ํ ์ค๋น๊ฐ ๋๋ฉด ํด๋น ํธ๋ฆฌ๋ฅผ ๋ฌธ์์ด๋ก ๋ณํํ ์ ์์ต๋๋ค. โ @mridgway
๋ค, ์ข์ต๋๋ค. ํ์ฌ ์๋ฒ ์ธก์์ ๊ตฌ์ฑ ์์๋ฅผ ๋ ๋ฒ ๋ ๋๋งํ๋ ๊ฒ์ด ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
React ๋ด์์ ์ง์๋๊ธฐ๋ฅผ ์ํ๋ ๊ฒ์ ์๋ก react-nexus ๋ฅผ ์ฐธ์กฐํ๊ณ ์ถ์ต๋๋ค. ์ค์ ๋ก DOM์ ๋ง์ดํธํ๊ฑฐ๋ ๋ฌธ์์ด์ ์์ฑํ์ง ์๊ณ ๊ตฌ์ฑ ์์ ํธ๋ฆฌ๋ฅผ ๊ตฌ์ถํ๋ค๋ ์ ์ ์ ์ธํ๊ณ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก mountComponent
์๋ ๋ฐฉ์์ ๋ค์ ์์ฑํฉ๋๋ค. ์ด๋ฅผ ํตํด ๊ตฌ์ฑ ์์ ํธ๋ฆฌ๋ฅผ ํ์ํ๊ณ ํธ๋ฆฌ๊ฐ ๊ตฌ์ถ๋๋ ๋์ ๋น๋๊ธฐ ๋ฉ์๋๋ฅผ ์คํํ ์ ์์ต๋๋ค. ์ด ๊ตฌํ์ ๋ฌธ์ ๋ ์ฒซ ๋ฒ์งธ ํธ๋ฆฌ๋ฅผ ๋ฒ๋ฆฌ๊ณ ์ด์จ๋ React.renderToString
๋ฅผ ํธ์ถํ์ง๋ง ์ฌ์ ๋ ๋๋ง ํธ๋ฆฌ๋ฅผ ๊ฐ์ ธ์์ ๋ ๋๋ง/๋ง์ดํธํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ฝ์ด ๋ด์์ ์ด ์์
์ ๊ธฐ๊บผ์ด ์ํํ๊ณ ์ถ์ง๋ง ๋ช ๊ฐ์ง ์ง์นจ์ด ํ์ํฉ๋๋ค. ์๊ตฌ ์ฌํญ ์ค ํ๋๋ ๋น๋๊ธฐ๋ก ์ธํด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ReactContext
๋ฅผ ์ ์ญ์ ์ผ๋ก ์ฐธ์กฐํ์ง ์๋๋ก ํ๋ ๊ฒ์
๋๋ค. ์ด์ ๊ด๋ จํ์ฌ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ ๋ค๋ฅธ ์ ์ญ์ด ์์ต๋๊น?
@mridgway ๋ด๊ฐ ์ค์ํ์ง ์์๋ค๋ฉด ๊ธ๋ก๋ฒ ReactContext
๋ ํธํ๋๋ ๊ฒ์ผ ์ ์์ผ๋ฉฐ 0.14์์ ์ฌ๋ผ์ง ๊ฒ์
๋๋ค. ํ์ง๋ง ์ ๊ฐ _์๋ง๋_ ํ๋ฆด ์๋ ์์ต๋๋ค.
@gaearon ์, withContext ์ง์ ์ค๋จ์์ ์ป์ ์๋ฏธ์ ๋๋ค.
:+1: ์ด ATM์ react-router
๋ฅผ ์ฌ์ฉ ์ค์
๋๋ค. @mridgway ์ ์ ๊ทผ ๋ฐฉ์์ ๋งค์ฐ ํฉ๋ฆฌ์ ์ผ๋ก ๋ค๋ฆฝ๋๋ค.
์ด ๋ฌธ์ ์ ๋ํ ์ฝ๊ฐ ๋ค๋ฅธ ๊ฒฌํด๋ ๋ฒ๋ค๋ฌ(์: webpack)์์ ์์ฑ๋ ์ฝ๋ ์ฒญํฌ์ ๋น๋๊ธฐ์ ๋ก๋๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
์ด ํฐ์ผ( https://github.com/rackt/react-router/issues/1402) ์์ ๋
ผ์๋ ๋ฐ์ ๊ฐ์ด ๋น๋๊ธฐ ๋ ๋๋ง ์ง์์ ๋ฌธ์ ๋ ๊ด๋ จ ์ฒญํฌ๊ฐ ์ฒซ ๋ฒ์งธ์์ ์์ง ๋ก๋๋์ง ์์๊ธฐ ๋๋ฌธ์ ์ด๊ธฐ ๋ ๋๋ง์ด null๋ก ํ์๋๋ค๋ ๊ฒ์
๋๋ค. ๋ ๋ ํจ์ค๋ก ์ธํด DOM ๋ฃจํธ์ <noscript>
๊ฐ ๋ฐ์ํ๊ณ ์ฒดํฌ์ฌ์ด ์คํจํฉ๋๋ค. ๋์ค์ ๋ชจ๋ ๊ฒ์ด ๋น ๋ฅด๊ฒ ์ ์๋ฆฌ์ ๋์ด์ง๋ง, ํนํ ๋ค์ด๋ก๋ํ ์ฒญํฌ๊ฐ ์ ์ ํ ํฌ๊ธฐ(์: > 30KB)์ธ ๊ฒฝ์ฐ ๋ก์ปฌ์์ ์์
ํ ๋ UI์์ ๊น๋ฐ์์ด ๋ฐ์ํ๊ณ ํ์ฅ์์ ๋ ๋๋น ์ง๋๋ค.
ํฐ ์ฑ์ ์ฌ๋ฌ ์ฒญํฌ๋ก ๋ถํ ํ๋ ๊ธฐ๋ฅ์ ์ฐ๋ฆฌ์๊ฒ ์ค์ํ๋ฉฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค(๋ฐ์ดํฐ ์ข ์์ฑ์ ๊ฐ์ ธ์ค๊ธฐ ์ํด ์๋ฒ์์ ๋ ๋๋งํ๊ธฐ ์ ์ ํต๊ณผํ ์ ์๋ ๋ฐ์ ๋ผ์ฐํฐ ๋ฐ ์ค์ฒฉ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ์ต๋๋ค). ์ด๊ฒ์ด ๋ง์ง๋ง ์กฐ๊ฐ์ ๋๋ค. ํ๋ก ํธ์๋์ฉ React ์๋ฃจ์ ์ผ๋ก ์์ ํ ์ ํํ๋ ๊ฒ์ ๋ฐฉํดํ๋ ํผ์ฆ์ ๋๋ค.
@anatomic ๊ทธ๊ฒ์ React์ ์ฑ ์์ด ์๋๋๋ค. ์ ์ ํ๊ฒ ์ฒญํฌํ๊ณ ํ์ํ ๋ชจ๋ ์ฒญํฌ๊ฐ ๋ก๋๋ ๋๊น์ง ๋ ๋๋ง์ ์ฐ๊ธฐํ๋ ๊ฒ์ ์ฌ๋ฌ๋ถ์ ์ผ์ ๋๋ค. ๋ฌ๋ฆฌ ๋งํ์๋ฉด, ์ปดํฌ๋ํธ ์ค ํ๋๊ฐ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ข ์๋์ด ์๋ ๊ฒฝ์ฐ ์ด๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์ ๋ง์กฑ์ํค๋ ๊ฒ์ด ๋ถ๋ช ํ ๋ฌธ์ ์ ๋๋ค. React๋ ์๋ํ๋๋ผ๋ ์ด๋ฅผ ์ํํ ์ ์์ผ๋ฏ๋ก ์ ๋ฐ์ ์ผ๋ก ๋์ผํ๊ฒ ์ ์ฉ๋ฉ๋๋ค.
<WaitFor for={MyAsyncLoadedCompSignal} until={...} then={() => <MyAsyncLoadedComp ... />} />
์ ๊ฐ์ด ์์ ์๊ฒ ๋ ์ ํฉํ ๋์ฒด ์ ๋ต์ ์์ ๋กญ๊ฒ ๊ตฌํํ์ธ์. ๊ทธ๋ฌ๋ ์ด๊ฒ๋ค์ ๋ณธ์ง์ ์ผ๋ก ๋
๋จ์ ์ด๋ฉฐ React๊ฐ ์ ๊ณตํด์ผ ํ๊ฑฐ๋ ์ ๊ณตํด์ผ ํ๋ ๊ฒ์ด ์๋๋ฏ๋ก ์ปค๋ฎค๋ํฐ์ ๋งก๊ธฐ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค.
React ๊ตฌ์ฑ ์์์ ๋ฒ์ ๋ฐ์ ์๋ ๋น๋๊ธฐ ํญ๋ชฉ์ ์ ์งํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
import React from 'react';
import Layout from './components/Layout';
import NotFoundPage from './components/NotFoundPage';
import ErrorPage from './components/ErrorPage';
const routes = {
'/': () => new Promise(resolve => {
require(['./components/HomePage'], HomePage => { // Webpack's script loader
resolve(<Layout><HomePage /></Layout>);
});
}),
'/about': () => new Promise(resolve => {
require(['./components/AboutPage'], AboutPage => { // Webpack's script loader
resolve(<Layout><AboutPage /></Layout>);
});
})
};
const container = document.getElementById('app');
async function render() {
try {
const path = window.location.hash.substr(1) || '/';
const route = routes[path];
const component = route ? await route() : <NotFoundPage />;
React.render(component, container);
} catch (err) {
React.render(<ErrorPage error={err} />, container);
}
}
window.addEventListener('hashchange', () => render());
render();
Webpack Code Splitting , React.js Routing from Scratch ๋ฐ react-routing (๊ณง ์ ๊ณต ์์ )์ ์ฐธ์กฐํ์ธ์.
@syranide ๊ณ์ ๋ ธ๋ ฅํ๊ฒ ์ง๋ง ์์ ๋งํ ๊ฒ์ฒ๋ผ ๋ฐ์ด๋๋ฆฌ๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ์ฐ๋ฆฌ๋ react-router๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ๋ผ์ฐํฐ๊ฐ React ํ๊ฒฝ ์ธ๋ถ์ ์๋ ๊ฒ์ด ์๋๋ผ ๊ตฌ์ฑ ์์์ด๊ธฐ ๋๋ฌธ์ ํผํฉ์ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
<WaitFor ... />
์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ค๋ฉด ์ฒซ ๋ฒ์งธ ๋ ๋๋ง์์ ์ฌ์ ํ ์ฝํ
์ธ ์ ๊น๋ฐ์/์์ค์ ์ ๋ฐํ๋ ๋ค๋ฅธ DOM์ ์ป์ ์ ์์ต๋๊น?
๋ง์ฝ ์ฐ๋ฆฌ๊ฐ
์ ๊ทผ ๋ฐฉ์, ํ์คํ ์ฒซ ๋ฒ์งธ ๋ ๋๋ง์์ ์ฌ์ ํ ์ฝํ ์ธ ์ ๊น๋ฐ์/์ฌ๋ผ์ง์ ์ ๋ฐํ๋ ๋ค๋ฅธ DOM์ ์ป์ ์ ์์ต๋๊น?
๊น๋ฐ์์ ์ํ์ง ์๋ ๊ฒฝ์ฐ(์ผ๋ถ๋ ํ์) ๋ ๋๋ง ์ ์ ์์กดํ๋ ๋ชจ๋ ์ฒญํฌ๊ฐ ๋ก๋๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋ฌธ์ ์
๋๋ค. webpack์ ์ฆ์ require.resolve
ํฉ๋๋ค.
์ถ์ . ๋ค, react-router์ ๋น์ ์ด ์ฌ์ฉํ๋ ๋ค๋ฅธ ๊ฒ๋ค์ ํ์คํ ์๋ฃจ์ ์ ๋ณต์กํ๊ฒ ๋ง๋ค์ง๋ง ์ฌ์ ํ React๊ฐ ํด๊ฒฐํด์ผ ํ ๋ฌธ์ ๋ ์๋๋๋ค.
๊น๋ฐ์์ ์ํ์ง ์๋ ๊ฒฝ์ฐ(์ผ๋ถ๋ ํ์) ๋ ๋๋งํ๊ธฐ ์ ์ ์์กดํ๋ ๋ชจ๋ ์ฒญํฌ๊ฐ ๋ก๋๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋ฌธ์ ์ ๋๋ค. webpack์ ๊ธฐ๋ณธ์ ์ผ๋ก require.resolve๋ฅผ ์ ๊ณตํฉ๋๋ค.
require.resolve
์ ๋ํ ๋์ ์ดํด๋ ๊ทธ๊ฒ์ด ๋ชจ๋ ID์ ๋๊ธฐ ์กฐํ์ด๊ณ ์๋ฒ๋ก์ ์ฌํ์ ํฌํจํ์ง ์๋๋ค๋ ๊ฒ์ด์์ต๋๋ค. ์ฒญํฌ ๋ก๋ฉ์ ๊ด๋ฆฌํ๊ธฐ ์ํด require.ensure
๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
์ฐ๋ฆฌ ์ฝ๋๋ฅผ ๋ค์ ๋ณด๋ฉด ๋ฐ์ ๋ผ์ฐํฐ๊ฐ ์๋ฒ์์ ๋ ๋๋งํ๋ค๊ณ ์๊ฐํ๊ฒ ๋ง๋ ๋ค์ ํ์ค ํด๋ผ์ด์ธํธ ์ธก ์ ๊ทผ ๋ฐฉ์์ ๋ฐ๋ฅด๋ฉด ๋ฌธ์ ๋ฅผ ์ฐํํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
const history = new BrowserHistory();
if (typeof history.setup === "function") {
history.setup();
}
Router.run(routes, history.location, (err, initialState, transition) => {
React.render(<Provider redux={redux}>{() => <Router key="ta-app" history={history} children={routes} />}</Provider>, document.getElementById('ta-app'));
});
๋๋ ๊ทธ๊ฒ์ ์กฐ์ฌํ ๊ฒ์ ๋๋ค. require.resolve์ ๋ํ ๋์ ์ดํด๋ ๊ทธ๊ฒ์ด ๋ชจ๋ ID์ ๋๊ธฐ ์กฐํ์ด๊ณ ์๋ฒ๋ก์ ์ฌํ์ ํฌํจํ์ง ์๋๋ค๋ ๊ฒ์ด์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ฒญํฌ ๋ก๋ฉ์ ๊ด๋ฆฌํ๊ธฐ ์ํด require.ensure๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
์ฃ์กํฉ๋๋ค. ์, require.ensure
. ์ฝ๋ฐฑ์ ๋ชจ๋ ์ข
์์ฑ์ด ์ถฉ์กฑ๋ ๋๋ง ์คํ๋๋ฏ๋ก ๊ทธ ์์ render/setState๋ฅผ ๋ฃ์ผ๋ฉด ๋ฉ๋๋ค.
์๊ฒ ์ต๋๋ค. ๊ทธ๋ ๊ฒ ํ๊ณ ์์์ต๋๋ค. ๋ต๋ณ ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ์ด๊ฒ์ react-router์์ ๋ค๋ฃจ์ด์ผ ํ ํ์๊ฐ ์๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋ฏ๋ก ๊ฑฐ๊ธฐ์์ ํ ๋ก ์ ๊ณ์ํ ๊ฒ์ ๋๋ค. ์ด ๋ํ๋ฅผ ํ๊ธฐ์ ์๋ชป๋ ์ฅ์์๋ค๋ฉด ์ฃ์กํฉ๋๋ค!
require.ensure
๊ฐ ๊ฐ์ผ ํ ๊ธธ์ด๋ผ๋ ๊ฒ์ด ๋ง์ต๋๋ค. ์ฐ๋ฆฌ์ ๊ถ๊ทน์ ์ธ ๋ฌธ์ ๋ ํ์ฌ ๋ฐฉ๋ฌธ ์ค์ธ ๊ฒฝ๋ก์ ์ฐ๊ฒฐ๋์ด์ผ ํ๋ฏ๋ก ๋ผ์ฐํฐ์ ์ง์ ์ฐ๊ฒฐ๋์ด์ผ ํ๋ค๋ ๊ฒ์
๋๋ค. react-router๋ ๋ ๋ ํธ๋ฆฌ์ ์ฐ๊ฒฐํ๋ ๊ตฌ์ฑ ์์ ๊ธฐ๋ฐ์
๋๋ค. ์์ ํดํน์ด ์์ผ๋ฉด ๋ชจ๋ ๊ฒ์ด ๋น๋๊ธฐ์์ผ๋ก ๋ก๋๋๊ธฐ ์ ์ ํธ๋ฆฌ๋ฅผ ๋ณด๋ ๋ฐฉ๋ฒ๊ณผ ์ธ์ฐ๊ฒ ๋ฉ๋๋ค(๋๋ ์ต์์ ์์ค์์ ๊ด๋ จ ์ฒญํฌ๋ฅผ ๋ก๋ํ ์ ์๋๋ก ๋ผ์ฐํ
๋
ผ๋ฆฌ๋ฅผ ๋ณต์ ).
require.ensure๊ฐ ๊ฐ์ผ ํ ๊ธธ์ด๋ผ๋ ๋ง์์ด ๋ง์ต๋๋ค. ์ฐ๋ฆฌ์ ๊ถ๊ทน์ ์ธ ๋ฌธ์ ๋ ํ์ฌ ๋ฐฉ๋ฌธ ์ค์ธ ๊ฒฝ๋ก์ ์ฐ๊ฒฐ๋์ด์ผ ํ๋ฏ๋ก ๋ผ์ฐํฐ์ ์ง์ ์ฐ๊ฒฐ๋์ด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค. react-router๋ ๋ ๋ ํธ๋ฆฌ์ ์ฐ๊ฒฐํ๋ ๊ตฌ์ฑ ์์ ๊ธฐ๋ฐ์ ๋๋ค. ์์ ํดํน์ด ์์ผ๋ฉด ๋ชจ๋ ๊ฒ์ด ๋น๋๊ธฐ์์ผ๋ก ๋ก๋๋๊ธฐ ์ ์ ํธ๋ฆฌ๋ฅผ ๋ณด๋ ๋ฐฉ๋ฒ๊ณผ ์ธ์ฐ๊ฒ ๋ฉ๋๋ค(๋๋ ์ต์์ ์์ค์์ ๊ด๋ จ ์ฒญํฌ๋ฅผ ๋ก๋ํ ์ ์๋๋ก ๋ผ์ฐํ ๋ ผ๋ฆฌ๋ฅผ ๋ณต์ ).
๋๋ react-router์ ์ต์ํ์ง ์์ง๋ง ์ฌ์ ํ ๋จ์ํ setRoute(...)
=> require.ensure([], function() { require(...); setRoute(...); })
๋ผ๊ณ ์๊ฐํ๋๋ฐ ์ค์ ๋ก๋ ์ค์ฉ์ ์ด์ง ์์ผ๋ฏ๋ก ๋ค๋ฅธ ์์ค์ ๊ฐ์ ์ฐธ์กฐ๋ฅผ ์๊ฐํฉ๋๋ค. ๊ฒฝ๋ก ๋งต๊ณผ ๊ฐ๊ฐ์ ๋ํ ๋น๋๊ธฐ require.ensure
๋ก๋. function asyncSetRoute(...) { loadRoute(route, function() { setRoute(...); }}
๋์ฐ๋ฏธ๋ฅผ ์์ฑํ๋ฉด ์ด์ ๋์ asyncSetRoute
๋ฅผ ํธ์ถํ๊ณ ๋ชจ๋ ๊ฒ์ด ์ค๋น๋ ๋๊น์ง ๋ผ์ฐํฐ ์
๋ฐ์ดํธ๋ฅผ ์ฐ๊ธฐํฉ๋๋ค.
์์ฌ ์ฝ๋ ๋ฐ ์ผ์ข ์ ์ผ๋ฐ, ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ ๋์๊ฒ ์ ๋ฐ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ฒ๋ผ ๋ณด์ ๋๋ค. ๋ฐ์ ๋ผ์ฐํฐ๊ฐ ์ด๊ฒ์ ์ ๊ณตํด์ผ ํ ์๋ ์๊ณ ๊ทธ๋ ์ง ์์ ์๋ ์์ต๋๋ค. ์๋ง๋ ์ธ๋ถ ๋์ฐ๋ฏธ๋ก ์ ๊ณต๋๋ ๊ฒ์ด ์ด์์ ์ผ ๊ฒ์ ๋๋ค. ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
๊ทธ๋์ ๋ช ์๊ฐ ๋์ ์กฐ์ฌํ ๋์ ์์์ ์๋๋ก(?) ๋ชจ๋ ๊ฒ์ ๊ณต๊ธํ์ง ์๋ ํ ์๋ฒ ์ธก ๋ ๋๋ง์ด _ ๋ถ๊ฐ๋ฅ _ํ๋ค๋ ๊ฒ์ ์ด์ ๋ง ํ์ธํ์ต๋๋ค.
๊ฐ๋ฅํ ๋จ๊ธฐ ์๋ฃจ์
:
A. ์ ์ฅ์๋ฅผ ๋ฏธ๋ฆฌ ์ฑ์ฐ๊ณ ์๋ฒ ์ธก ๋ก๋ฉ์ ๋๊ธฐ์์ผ๋ก ๋ง๋ญ๋๋ค.
B. ํ๋์ ๋ฐ์ดํฐ ๊ฐ์ฒด๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ๊ฐ์ ธ์จ ํ ์์์๋ถํฐ ํ๋์ ๋ฐ์ดํฐ ์ ๋ ฅ์ผ๋ก ๋ชจ๋ ๊ฒ์ ๊ณต๊ธํฉ๋๋ค.
์ฌ: '์'. ๋ ๋ ๊ตฌ์กฐ๊ฐ ์ด๋ป๊ฒ ์๊ฒผ๋์ง ์ด๋ฏธ ์๊ณ ์์ง ์์ผ๋ฉด ์๋ํ์ง ์์ต๋๋ค. ๋ด ๋ค์ํ โโ์ปฌ๋ ์ /๋ชจ๋ธ/API ์ข ์์ฑ์ ์๊ธฐ ์ํด ๋ ๋๋งํด์ผ ํฉ๋๋ค. ๋ํ ๋ ๊ฐ์ ์๋ก ๋ค๋ฅธ API ์์ด ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ํด๋ผ์ด์ธํธ์์ ๋น๋๊ธฐ์ ์ผ๋ก ์ํํ์ง๋ง ์๋ฒ์์๋ ๋๊ธฐํํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น?
์ฌ: 'B'. ๊ธฐ๋ณธ์ ์ผ๋ก ์์ ๊ฐ์ ๋ฌธ์ ์ ๋๋ค. ์ฌ๋๋ค์ ๊ฐ๊ฐ์ ๊ฒฝ๋ก์ ํจ๊ป ์ฌ์ฉํ๊ธฐ ์ํด ์ฝ๊ฐ์ ์ข ์์ฑ JSON์ ๋ง๋ค์ด์ผ ํฉ๋๊น?
React ์ง์ ์๋ฃจ์ ์ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ๋ค๋ฅธ ๋จ๊ธฐ ์๋ฃจ์ ์ด ์์ต๋๊น? ์ฌ์ฉ์ ํ ์ง ํฌํฌ ๋๋ ํ๋ฌ๊ทธ์ธ์ด ์์ต๋๊น? https://www.npmjs.com/package/react-async ?
@NickStefan
๋ฌธ์ ๊ฐ ์ดํด๊ฐ ๋์ง ์์ต๋๋ค. :-(
fetchData
์ ๊ฐ์ ์ ์ ๋ฉ์๋๋ฅผ ์ ์ํฉ๋๋ค.fetchData
๋ฅผ ๊ฐ์ ธ์ ๋ ๋๋ง ์ ์ ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค. ์ด๊ฒ์ Flux ๋๋ Redux ์คํ ์ด ์ธ์คํด์ค๋ฅผ ๋ฏธ๋ฆฌ ์ฑ์ธ ๊ฒ์
๋๋ค. ์ ์ฅ์ ์ธ์คํด์ค๋ ์ฑ๊ธํค์ด ์๋๋๋ค. ํน์ ์์ฒญ์ ๋ฐ์ธ๋ฉ๋๋ฏ๋ก ์์ฒญ์ด ๊ฒฉ๋ฆฌ๋ ์ํ๋ก ์ ์ง๋ฉ๋๋ค.๋ค์์ ์ด ์ ๊ทผ ๋ฐฉ์์ ์ค๋ช ํ๋ Redux์ ๋ํ ์ข์ ์์ต์์ ๋๋ค. https://medium.com/@bananaoomarang/handcrafting -an-isomorphic-redux-application-with-love-40ada4468af4
@gaearon ํผ๋์
์ด๊ฒ์ ์ข์ ํ๋ญ์ค ๊ดํ์ด์ง๋ง ์ ์ฌ์ ์ผ๋ก ์ ํ์ ์ด์ง ์์ต๋๊น? ๋งค์ฐ ๋ค๋ฅธ ๋ฐ์ดํฐ๊ฐ ํ์ํ ๋ทฐ ํธ๋ฆฌ์ ๋งจ ์๋์ ์์ ๊ตฌ์ฑ ์์๋ฅผ ์ถ๊ฐํ๋ฉด ๋ฃจํธ์์ ๋ฐ์ดํฐ ์ข ์์ฑ์ ํธ์งํด์ผ ํฉ๋๋ค.
๋ด๊ฐ ์๊ตฌํ๋ ๊ฒ์ ๊น์ด ์ค์ฒฉ๋ ๊ตฌ์ฑ ์์๊ฐ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
๋ฃจํธ ๊ตฌ์ฑ ์์์ ๊ทธ๋ค์ ์๊ตฌ ์ฌํญ์ ์ถ๊ฐํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ฃจํธ๋ฅผ ํ์ ๊ตฌ์ฑ ์์๊ฐ ํ์๋ก ํ๋ ํ๋์ ํ์ ๊ตฌ์ฑ ์์์ ์ฐ๊ฒฐํ์ง ์์ต๋๊น?
@NickStefan with react-routing , ์๋ฅผ ๋ค์ด ๋น๋๊ธฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
import Router from 'react-routing/lib/Router';
import http from './core/http';
const router = new Router(on => {
on('/products', async () => <ProductList />);
on('/products/:id', async (state) => {
const data = await http.get(`/api/products/${state.params.id`);
return data && <Product {...data} />;
});
});
await router.dispatch('/products/123', component => React.render(component, document.body));
์ด๋ฌํ ์๋ฃจ์ ์ ์๋ํ์ง๋ง ๋ชจ๋ ๋ฐ์ดํฐ ํ๋ฆฌํ์น๊ฐ ๋ผ์ฐํฐ์ ๋ฐ์ธ๋ฉ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๊ฒ์ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ๋์ง ์์ง๋ง(URL์ด ํ์ด์ง์ ์์ด์ผ ํ๋ ๋ด์ฉ๊ณผ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ์ํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์) ์ผ๋ฐ์ ์ผ๋ก ์ ํ ์ฌํญ์ ๋๋ค. ๋ชจ๋ ๊ฒ์ ์์ฒด์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ ๋ฆฝํ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๊ตฌ์ฑ ์์(์: Twitter ์คํธ๋ฆผ, ๋๊ธ, ์บ๋ฆฐ๋)๋ฅผ ์์ฑํ ์ ์์ผ๋ฉฐ ๊ตฌ์ฑ ์์ ๊ณ์ธต์ ์ฝ์ ํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ์ด๊ฒ์ ๊ฐ๋ฅํ๊ฒ ํ๋ ์ ์ผํ ๋ฐฉ๋ฒ์ react-async ์ด์ง๋ง ์ด๊ฒ์ ๊ฑฐ์ ํดํน์ ๋๋ค.
๋๋ React ์ปดํฌ๋ํธ๊ฐ ๋จ์ํ ์ด๋ฐ ์์ผ๋ก ์ฌ์ฉ๋๋๋ก ์๋๋ ๊ฒ์ด ์๋๋ผ _controller_-views๋ณด๋ค ๋ ๋ง์ ๋ณด๊ธฐ๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค. ์๋ง๋ React๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ ํ ์๋ก์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ฑ์ฅํด์ผ ํ ๊ฒ์ ๋๋ค.
์ ๊ฟ์ ์ธ์ ๊ฐ Wordpress, Drupal ๋๋ Modx์ ๊ฐ์ React๋ฅผ ์ฌ์ฉํ์ฌ ์์ ํ CMS๋ฅผ ์์ฑํ ์ ์๊ฒ ๋๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ HTML/PHP ์ค๋ํซ ๋์ React ์ปดํฌ๋ํธ์์ ์น์ฌ์ดํธ๋ฅผ ๊ตฌ์ฑํ ๊ฒ์ ๋๋ค.
@NickStefan
๊ทํ์ ๋ชฉ๋ก์์ ์๋ฒ ๋ฐ์ดํฐ ์ข ์์ฑ์ ๋ํ ์๋ฃจ์ ์ด ๋ฃจํธ ๊ตฌ์ฑ ์์(์ ์ ๋ฐฉ๋ฒ/๋งํฌํ ๊ธฐ์ฌ)์์๋ง ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์ ์ ์ํ๋ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํ๋ ๊ฒ์ด ๋ง๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ฐ์ดํฐ ์ข ์์ฑ์ด ๋ฃจํธ์ ์ ์๋์ด ์์ผ๋ฉด ์ ์ฅ์ ๋ฑ์ ๋ฏธ๋ฆฌ ์ฑ์ฐ๋ ๊ฒ์ด ํจ์ฌ ์ฝ์ต๋๋ค.
๋ฃจํธ ๊ตฌ์ฑ ์์์ ๊ทธ๋ค์ ์๊ตฌ ์ฌํญ์ ์ถ๊ฐํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ฃจํธ๋ฅผ ํ์ ๊ตฌ์ฑ ์์๊ฐ ํ์๋ก ํ๋ ํ๋์ ํ์ ๊ตฌ์ฑ ์์์ ์ฐ๊ฒฐํ์ง ์์ต๋๊น?
๋ฃจํธ ์ฒ๋ฆฌ๊ธฐ ์์ค์์ ์ ํํ ๋ฃจํธ๊ฐ ์๋๋๋ค. ์ฑ์๋ ๋ง์ ๊ฒฝ๋ก ์ฒ๋ฆฌ๊ธฐ๊ฐ ์์ ์ ์์ต๋๋ค. ๋ํ React Router ์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ค์ฒฉ ๊ฒฝ๋ก ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ง์ ๋ฐฐ์ด ์ด ํฌํจ๋๋ฏ๋ก Promise.all
ํ ์ ์์ต๋๋ค. ์ด๊ฒ ๋ง์ด ๋ผ?
"๋ชจ๋ ๊ตฌ์ฑ ์์๊ฐ ์ข
์์ฑ์ ์ ์ธํ ์ ์์"๋งํผ ์ธ๋ถํ๋ ๊ฒ์ ์๋์ง๋ง ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๊ฒฝ๋ก ์ฒ๋ฆฌ๊ธฐ(์๋จ ๋ฐ ์ค์ฒฉ ์ฒ๋ฆฌ๊ธฐ)๋ก ์ ํํ๋ ๊ฒ์ด ์ ๊ฐ ์ํ๋ ์ ๋ถ๋ผ๋ ๊ฒ์ ์์์ต๋๋ค. ์๋์ props
๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ํ์ฉํ๋ ์์ํ ๊ตฌ์ฑ ์์๊ฐ ์์ผ๋ฏ๋ก ๊ฐ์ ธ์ค๋ _์์ง_์กฐ์ฐจ ํ์ง ์์ต๋๋ค. ๊ทธ๋ค์ด ๊ทธ๊ฒ์ ์์ฒญํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค.
"๋ชจ๋ ๊ตฌ์ฑ ์์๋ ์ข
์์ฑ์ ์ ์ธํ ์ ์์ต๋๋ค" ์ ๊ทผ ๋ฐฉ์์ ์ผ์ข
์ ์์ฒญ ์ผ๊ด ์ฒ๋ฆฌ ์๋ฃจ์
์ด ์๋ ํ ์ค์ฉ์ ์ด์ง ์์ต๋๋ค. <User>
๊ฐ API ํธ์ถ์ด ํ์ํ๋ค๊ณ ์ ์ธํ๊ณ ์ด์ 100๊ฐ์ <User>
๋ชฉ๋ก์ ๋ ๋๋งํ๋ค๊ณ ์์ํด ๋ณด์ธ์. 100๊ฐ์ ์์ฒญ์ ๊ธฐ๋ค๋ฆฌ์๊ฒ ์ต๋๊น? ์ด๋ฌํ ์ข
๋ฅ์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ์๊ตฌ ์ฌํญ ์ธ๋ถ์ฑ์ ์์ฒญ ์ผ๊ด ์ฒ๋ฆฌ ์๋ฃจ์
์ด ์๋ ๊ฒฝ์ฐ์๋ง ์๋ํฉ๋๋ค. ๊ทธ๊ฒ์ด ๋น์ ์๊ฒ ์ ํฉํ๋ค๋ฉด, Relay ๊ฐ ๋ฐ๋ก ๊ทธ๊ฒ์
๋๋ค. ํ์ง๋ง ์ด๋ฅผ ์ํด์๋ ํน๋ณํ ๋ฐฑ์๋๊ฐ ํ์ํฉ๋๋ค.
@NickStefan ํ์ฌ ๊ตฌ์ฑ ์์๋ณ ๋น๋๊ธฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ง์ํ์ง ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ์ถ๊ฐํ๊ณ ์ถ์ต๋๋ค. ์ด ๋ฌธ์ ๋ ์งํ ์ํฉ์ ์ถ์ ํ์ง๋ง ์๋ฌด๋ ์ด์ ๋ํด ์ ๊ทน์ ์ผ๋ก ์์ ํ์ง ์์ผ๋ฉฐ ๋๊ท๋ชจ ๊ตฌ์กฐ ์กฐ์ ์ด ํ์ํ๋ฏ๋ก ์๊ฐ์ด ๊ฑธ๋ฆฝ๋๋ค.
@gaearon
"๋ชจ๋ ๊ตฌ์ฑ ์์๋ ์ข ์์ฑ์ ์ ์ธํ ์ ์์ต๋๋ค" ์ ๊ทผ ๋ฐฉ์์ ์ผ์ข ์ ์์ฒญ ์ผ๊ด ์ฒ๋ฆฌ ์๋ฃจ์ ์ด ์๋ ํ ์ค์ฉ์ ์ด์ง ์์ต๋๋ค.
์ด๊ฒ์ ๋ํด ์ข ๋ ์๊ฐํ ํ์, ๋๋ ๋น์ ์ ๋ง์ ๋์ํฉ๋๋ค. ๋ด๊ฐ ์ฐพ๋ ๊ฒ์ ์ค์ ๋ก ์ค์ฉ์ ์ด์ง ์์ต๋๋ค.
๋ ์๋ ๋์ 100๋<UsersContainer>
๋ชจ๋ 100 ์ผ ๊ฐ ์๊ตฌ๋ฅผ ์์ต๋๋ค). ๊ทธ๋ฌ๋ ๋จ์ํ ์ปจ๋ฒค์
์ ๊ฐ๋ ๊ฒ์ "์ฌ๋๋ค์ด ํ์ฅํ ์ ์๋" ๊ฒ์ด ์๋๋๋ค. ๋ฃจํธ ๋๋ ๋ผ์ฐํฐ์ ๋ํ ๋ชจ๋ ์ข
์์ฑ์ ์ ์ฉํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค. Relay๋ ์ธ ๊ฐ์ง ๋ค๋ฅธ ์ปจํ
์ด๋(RelayContainer, RelayRootContainer, RelayRouter ๋ฑ)๋ฅผ ์ฌ์ฉํ์ฌ ๋ฃจํธ์์ ์ข
์์ฑ์ ์ ์ธํ๋๋ก ๊ฐ์ ํฉ๋๋ค. ์ด๋ ๋ณธ์ง์ ์ผ๋ก ์ข
์์ฑ ์ ์ธ์ ํธ๋ฆฌ ์๋ก "ํธ์ด์คํธ"ํ๋ ๊ฒ์ด ์ ์ผํ ๋ฐฉ๋ฒ์ด๋ผ๋ ์ ์ ์ฆ๋ช
ํฉ๋๋ค.
์๋
ํ์ธ์!
์ด์ ๋ํ ์
๋ฐ์ดํธ๊ฐ ์์ต๋๊น?
+1
๋๋ ๋น์ ์ด ์ ๋ง๋ก ์ด๊ฒ์ ๋ํด ์๊ฐํ๋ค๋ฉด, ๋น์ ์ ์ด๊ฒ์ ํ๊ณ ์ถ์ง ์๋ค๊ณ ์ฃผ์ฅํฉ๋๋ค. ๋๋ ์๋ React๊ฐ ๋น๋๊ธฐ ๋ ๋๋ง์ ํ๊ธฐ๋ฅผ ์ํ๋ค๊ณ ์๊ฐํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด ์ค๋ ๋์ ๋ค๋ฅธ ์ฌ๋๋ค์ ๊ทธ๋ ์ง ์๋ค๊ณ ํ์ ํ์ต๋๋ค.
๋ฆด๋ ์ด์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฃจํธ ์ปจํ ์ด๋ ์ ์ธ, ๋ฆด๋ ์ด ์ปจํ ์ด๋ ๋ฑ์ ์ฌ์ฉํ์ฌ ์ข ์์ฑ์ ํธ๋ฆฌ ์๋ก "ํธ์ด์คํธ"ํด์ผ ํฉ๋๋ค. ๋๊ธฐ ๋ ๋๋ง์ด ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์ ๋๋ค.
๋น๋๊ธฐ์ ๋ ๋๋ง์ ์ ๋ชฝ์ด ๋ ์ ์์ต๋๋ค. ์์ฒญ ์ ๋๋ฉ์ด์ ํ๋ ์์์ ๊ฐ๋ณ ์ ๋ฐ์ดํธ๋ฅผ ์ํํ๊ธฐ ์ํด ํดํน๋ ๋ฐฑ๋ณธ์ด ์๋ ํ์ฌ ์ฝ๋๋ฒ ์ด์ค์์ ์์ ํ ๊ฒฝํ์์ ์ด์ผ๊ธฐํฉ๋๋ค.
๋์. ๋๋ ์ด๊ฒ์ด ํ์ํ๋ค๊ณ ์๊ฐํ์ง๋ง ์ค์ ๋ก๋ ๋ทฐ๊ฐ ๋ก๋ํ ๋ฐ์ดํฐ๋ฅผ ์ง์ ํ๋๋ก ํ๋ ๊ฒ์ด ์๋๋๋ค. ๋ณด๊ธฐ๋ ๊ทธ ์์ฒด๊ฐ ์์ฒญ์ ๊ธฐ๋ฅ(์ธ์ ์ด ์๋ ๊ฒฝ์ฐ ์ฌ์ฉ์์ ์ํ)์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ํ์ ๊ธฐ๋ฅ์ ๋๋ค. ์ด๊ฒ์ด React์ ๋ชจ๋ ๊ฒ์ ๋๋ค. ๊ตฌ์ฑ ์์๊ฐ ๋ก๋ํด์ผ ํ ๋ฐ์ดํฐ๋ฅผ ์ง์ ํ๋๋ก ํ์ฉํ๋ ๊ฒ์ "๋จ๋ฐฉํฅ ๋ฐ์ดํฐ ํ๋ฆ" ์์ด๋์ด์ธ IMO์ ์๋ฐฐ๋ฉ๋๋ค.
๋ทฐ๊ฐ ๋ก๋ํ ๋ฐ์ดํฐ๋ฅผ ์ง์ ํ๋๋ก ํ๋ ๊ฒ์ ์ค์ ๋ก๋ ๊ฑฐ๊พธ๋ก์ ๋๋ค.
์ด๊ฒ์ด ์ฌ์ค์ธ์ง ์์ ํ ํ์ ํ ์ ์์ต๋๋ค. ๋๋๋ก ๊ตฌ์ฑ ์์๋ ๋ก๋ํ ๋ฐ์ดํฐ๋ฅผ ์๋ ์ ์ผํ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด ์ฌ์ฉ์๊ฐ ๋ฐฉ๋ํ ๋ ธ๋ ๊ทธ๋ํ๋ฅผ ํ์ํ ์ ์๋ ํ์ฅ ๊ฐ๋ฅํ ํธ๋ฆฌ ๋ณด๊ธฐ๊ฐ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํด์ผ ํ๋์ง ๋ฏธ๋ฆฌ ์ ์ ์์ต๋๋ค. ์ปดํฌ๋ํธ๋ง์ด ๊ทธ๊ฒ์ ์์๋ผ ์ ์์ต๋๋ค.
๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ๋ธ๋ฆฌ์ง๋ฅผ ํตํด ํต์ ํ๊ธฐ ์ํด ๋น๋๊ธฐ๊ฐ ํ์ํ ์น ์์ ์(#3092) ๋ด์์ React ์ฝ๋๋ฅผ ์คํํ๋ ์์ด๋์ด๋ฅผ ์ถ๊ตฌํ๋ค๋ฉด ์ด ๋ ผ์๊ฐ ํจ์ฌ ๋ ๊ด๋ จ์ฑ์ด ์์ ์ ์์ต๋๋ค.
ํฐ ํธ๋ฆฌ ๋ณด๊ธฐ์ ์์์ ์๋ฒ ์ธก์์ ์ด๋ฏธ ์ด๋ ค ์๋ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ์ฌ ๋ ๋๋งํ ์ ์๊ธฐ๋ฅผ ์ ๋ง๋ก ์ํ๋ค๋ฉด URL ๊ตฌ์กฐ์ ํด๋น ๊ฒฝ๋ก๋ฅผ ์ถ๊ฐํฉ๋๋ค. ์ด์ ๊ฐ์ ๋ณต์กํ ๊ตฌ์ฑ ์์๊ฐ ์ฌ๋ฌ ๊ฐ ์๋ ๊ฒฝ์ฐ GET ๋งค๊ฐ ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ํด๋น ์ํ๋ฅผ ๋ํ๋ ๋๋ค. ์ด๋ฐ ์์ผ๋ก ํด๋น ๊ตฌ์ฑ ์์๋ SSR์ ๋ชจ๋ ์ด์ ์ ์ป์ต๋๋ค. ํฌ๋กค๋ง ๊ฐ๋ฅํ๊ณ ๊ธฐ๋ก์ ์ฌ์ฉํ์ฌ ํ์ํ ์ ์์ผ๋ฉฐ ์ฌ์ฉ์๋ ๋ด๋ถ ๋ ธ๋์ ๋ํ ๋งํฌ๋ฅผ ๊ณต์ ํ ์ ์์ต๋๋ค. ์ด์ ์๋ฒ์์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ฒฐ์ ํ ์ ์๋ ๋ฐฉ๋ฒ๋ ์์ต๋๋ค. ์๋ต์ ๋ ๋๋งํ๊ธฐ ์ํด ๊ฐ์ ธ์ต๋๋ค.
update ๊ทธ๋ํ๋ฅผ ๋๋ฌด๋ก ์๋ชป ์๋ชป ์๊ณ ์์ง๋ง ์ฌ์ ํ ํด๋น ๊ทธ๋ํ์ ๋ํ ์ฌ์ฉ์ ๋ณด๊ธฐ์ ์ํ๊ฐ URL ๊ตฌ์กฐ๋ก ํ์๋์ด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ํ ์ค์ ๋ก React์์ ์์ ํ๋ค๋ ๊ฒ์ ๊นจ๋ซ์ง ๋ชปํ์ต๋๋ค. ๋ฐ์ดํฐ ๊ณ์ธต์ ๋ทฐ์ ๋ํ์ ์ผ๋ก ํตํฉํ๊ธฐ ์ํ ์ผ๋ถ ํ๋ ์์ํฌ์์ ์์ ํ๋ ๊ฒฝ์ฐ ์ ๋ง ์ข์ต๋๋ค. ๊ทธ๋ฌ๋ ๋๋ ๊ทธ๊ฒ์ด ๋ณด๊ธฐ์ ์์ญ์ ๋์ด์๊ณ React๊ฐ ์ ์ฒด ์คํ ์ปจํธ๋กค๋ฌ์ ์ญํ ์ ํด์๋ ์ ๋๋ค๋ ๋ฐ ๋์ํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ์ฒด ์ค๋ ๋๋ฅผ ์ฝ์ง ์์์ผ๋ฏ๋ก ์ด๋ฏธ ๋ ผ์๋์๋ค๋ฉด ์ฃ์กํฉ๋๋ค.
์ ๋ง ๋์์ด ๋ ํ ๊ฐ์ง๋ ๊ตฌ์ฑ ์์๋ฅผ "์์/์ธ์คํด์คํ"ํ๊ณ ์๋ช
์ฃผ๊ธฐ ๋ฉ์๋๋ฅผ ์คํํ์ง๋ง ๊ฐ๋ฐ์๊ฐ ๊ตฌ์ฑ ์์๋ฅผ html ๋ฌธ์์ด๋ก ๋ ๋๋งํ ์ค๋น๊ฐ ๋ ์์ ์ ๊ฒฐ์ ํ๊ฒ ํ๋ react-dom/server
๋ฉ์๋๊ฐ ์๋ ๊ฒฝ์ฐ์
๋๋ค. . ์๋ฅผ ๋ค์ด ๊ฐ๋ฐ์๋ setTimeout ๋๋ ๋ ์์ ์ ์ธ ๊ฒ์ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ๋ฉ์๋๊ฐ ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด ์ ์์ต๋๋ค.
์ด๊ฒ์ ํ์ฌ ์ด๊ฒ์ ๋ฌ์ฑํ๊ธฐ ์ํด redux์ ํจ๊ป ์ฌ์ฉํ๊ณ ์๋ "ํดํน"์ ๋๋ค.
// start/instantiate component
// fires componentWillMount methods which fetch async data
ReactDOM.renderToString(rootEle)
// all my async methods increment a `wait` counter
// and decrement it when they resolve
const unsubscribe = store.subscribe(() => {
const state = store.getState()
// as a result, when there are no more pending promises, the wait counter is 0
if (state.wait === 0) {
unsubscribe()
// all the data is now in our redux store
// so we can render the element synchronously
const html = ReactDOM.renderToString(rootEle)
res.send(html)
}
})
์ด ์ ๊ทผ ๋ฐฉ์์ ๋ฌธ์ ๋ ๋ ๋ฒ์งธ ReactDOM.renderToString
๊ฐ ๋ชจ๋ componentWillMount
๋ฉ์๋๋ฅผ ๋ค์ ์คํํ์ฌ ๋ถํ์ํ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋ฐ์์ํจ๋ค๋ ๊ฒ์
๋๋ค.
์๋ค ์! ์ด๊ฒ์ ํ์ฌ ์์
์ค์ธ ๊ฒ์
๋๊น? ์ด ๋ฌธ์ ์ ์ค์์ฑ์ด ์ปค์ง๊ณ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ต๊ทผ์ react redux์ connect
๋ฅผ dataConnect
๋ก ํ์ฅํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ง๋ค์์ต๋๋ค. ์ฌ๊ธฐ์ ์ปจํ
์ด๋ ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ๋ ์ง์ ํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์ ๋ฐํ์์ ๋ฒ๋ค๋ก ์ ๊ณต๋๊ณ ๋จ์ผ ์์ฒญ์์ GraphQL๋ก ์ฟผ๋ฆฌ๋ฉ๋๋ค. ์ด๊ฒ์ด ๊ตฌ์ฑ ๊ฐ๋ฅ์ฑ๊ณผ ๊ฒฉ๋ฆฌ๋ฅผ ์ด์งํ๊ณ ๋ ์ฑ๋ฅ์ด ์ข์ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋ณด์ฅํ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ด ๋ฐ์ดํฐ ์ฌ์์ ๋ฏธ๋๋ผ๊ณ ์๊ฐํฉ๋๋ค. (Relay์์ ๋ณธ ๋ชจ๋ ๊ฐ๋
)
์์ ๋ฌธ์ ๋ ์๋ฒ ์ธก ๋ ๋๋ง์ ๋๋ค. ๋ด๊ฐ ์ด๋ค ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์ผ๋ก ๋๋ ๊ฒ์ธ์ง ์ ์ ์ผ๋ก ๋ถ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ํ์ฌ DB์์ ์ฟผ๋ฆฌํ ๋ฒ๋ค์ ๊ฐ์ ธ์ค๊ธฐ ์ํด ํ ๋ฒ ๋ ๋๋งํด์ผ ํ๊ณ redux ์ ์ฅ์๋ฅผ ์จ๊ธด ๋ค์ ์ต์ข ๋ฌธ์์ด์ ์ป๊ธฐ ์ํด ๋ค์ ๋ ๋๋งํด์ผ ํฉ๋๋ค. . ๋ฌธ์ ๋ @olalonde ์ ๋ฌธ์ ์ ์ ์ฌํฉ๋๋ค.
๋ฐ์ ์์ ํธ๋ฆฌ์ ๋ํ ์์ ๋ฐ ์ ๋ฐ์ดํธ๋ฅผ ํธ๋ฆฌ๊ฑฐํ๊ณ ์์ฒญ ์ DOM ๋ฌธ์์ด ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค๋ฉด ํ์์ ์ผ ๊ฒ์ ๋๋ค. ๋ด๊ฐ ๊ทธ๋ฆผ์ ๊ทธ๋ฆฌ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
const virtualTree = ReactDOM.renderVirtual(rootEle);
// get the bundled query from redux store for example
const bundle = store.getState().bundle;
// Fetch the data according to the bundle
const data = fetchDataSomehow(bundle);
// hydrate store
store.dispatch({type: 'hydrate', data});
// components that should update should be marked on the virtual tree as 'dirty'
virtualTree.update(); // this would only update the components that needed update
const domString = virtualTree.renderToString(); // final result
๋ค๋ฅธ ์ต์ ์ ๋ชจ๋ ํํฌ๊ฐ ์กด์ฌํ๊ณ didMount์ ๊ฐ์ด ์๋ํ๋ ํด๋ผ์ด์ธํธ ์ธก์์์ ๊ฐ์ด ๋ง์๋๋ก ์ ๋ฐ์ดํธํ๋๋ก ํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ DOM์ ๋ณ๊ฒฝํ๋ ๋์ ๊ฐ์ DOM ํํ์ ๋ณ๊ฒฝํ๊ณ ์์ฒญ ์ ๋ฌธ์์ด๋ก๋ ๋ ๋๋งํฉ๋๋ค.
์ฌ๋ฌ๋ถ์ ์ด๋ป๊ฒ ์๊ฐํ์ธ์? ๊ณ ๋ คํด์ผ ํ ์ฌํญ์ด ์์ต๋๊น? ์๋๋ฉด ์ ๊ฐ ์์ ํ ์๋ชป ๋ณด๊ณ ์์ต๋๊น?
์๋ ๋ชจ๋. ์ ๋ ์ด ๋ฌธ์ ๋ฅผ ๊ตฌ๋ ํ์ง 1๋ ์ ๋ ๋์์ต๋๋ค. ๊ทธ ๋น์์๋ ๊ตฌ์ฑ ์์๊ฐ ๋ชจ๋ํ์ ๊ธฐ๋ณธ ๋จ์์๊ธฐ ๋๋ฌธ์ ๊ตฌ์ฑ ์์ ๋ด์์ ๋ก๋ํด์ผ ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ง์ ํ ์ ์์ด์ผ ํ๋ค๊ณ ์๊ฐํ์ต๋๋ค. ์ด ๋ฌธ์ ๋ ๋์๊ฒ ์ ๋ง ์ค์ํ๊ณ , ๋๋ ๊ทธ๊ฒ์ด React์ ๋ค์ ๋ฒ์ ์์ ๋ฐ๋์ ํด๊ฒฐ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค.
๊ทธ ์ดํ๋ก ์ ๋ REST/HATEOS ์ด๋ฉด์ ์ด์์ ๋ํด ํจ์ฌ ๋ ๊น์ ์กด๊ฒฝ์ฌ์ ๊ฐ๊ฒ ๋์์ต๋๋ค. ๊ทธ ์ง์นจ ์์น์ด ๋ค์๊ณผ ๊ฐ์ ๊ฒฝ์ฐ ์ ํ๋ฆฌ์ผ์ด์ ์์คํ (๋ธ๋ผ์ฐ์ , ํฌ๋กค๋ฌ, ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ, ํ๋ก์, CDN ๋ฑ)์์ ๋ํ๋๋ ๋๊ท๋ชจ ๋จ์์ฑ ๋๋ฌธ์ ๋๋ค. ๋ฐ๋๋ค. ์ด ๋ฌธ์ ์ ๊ด๋ จํ์ฌ _URL์ ์ ํ๋ฆฌ์ผ์ด์ ์ํ์ ์ง์ ํ ํํ์ด์ด์ผ ํฉ๋๋ค_. ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๋ฐ ํ์ํ ์ ๋ณด๋ฅผ ๊ฒฐ์ ํด์ผ ํฉ๋๋ค. ๋ทฐ ๋ ์ด์ด์ธ React๋ ์ด๊ฒ์ ๊ฒฐ์ ํด์๋ ์ ๋ฉ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ถํด์ผ ํฉ๋๋ค. ๋ณด๊ธฐ๋ ๋ฐ์ดํฐ์ ๊ธฐ๋ฅ์ด๊ณ ๋ฐ์ดํฐ๋ URL์ ๊ธฐ๋ฅ์ ๋๋ค .
๋๋ ์ด๊ฒ์ด ์ข์ ์์ด๋์ด์ด์ง๋ง ํ์ค ์ธ๊ณ๋ ์ด๊ฒ์ด ์๋ํ๊ธฐ์๋ ๋๋ฌด ๋ณต์กํ๋ค๋ ๋ง์ ๊ณ์ ๋ค์๊ธฐ ๋๋ฌธ์ ๊ณผ๊ฑฐ์ ์ด๊ฒ์ ๋ฒ๋ฆฌ๋ ๊ฒ์ ์ฃผ์ ํ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋๋๋ก ๋๋ ํ ๋ฐ ๋ฌผ๋ฌ์์ ๋ด๊ฐ ๋๋ฌด ํํ์ ์ด๊ฑฐ๋ ๋๋ฌด ์ด์์ฃผ์์ ์ด์ง ์๋ ํ๋ ์๊ฐ์ ํ๊ฒ ๋ง๋๋ ์๋ฅผ ๋ฃ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ฌํ ์๋ฅผ ์๊ณ ํ๋ฉด์ ๋ถ๊ฐํผํ๊ฒ URL์์ ์์ฉ ํ๋ก๊ทธ๋จ ์ํ๋ฅผ ๋ํ๋ด๋ ํฉ๋ฆฌ์ ์ธ ๋ฐฉ๋ฒ์ ์ฐพ์ต๋๋ค.
๊ทธ๋ ์ง ์์๋ค๋ฉด ๊ฐ์ง ์ ์์์ ๊ทธ ๋ชจ๋ ์ผ์ ๋ํด ๋ฌด์์ ์ป์ต๋๊น?
next
๋งํฌ. FB ๊ทธ๋ํ API๊ฐ ์ด์ ๋ํ ์ข์ ์์
๋๋ค.app.get("*", theOneTrueClientonaserverEntryPoint)
๋ก ์ผ์น์ํค๋ ๋์ ์๋ํ ๋๋ก ์๋ฒ ์ ํ๋ฆฌ์ผ์ด์
ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค. 200 OK\n\n{status: "error"}
๋์ ์์ฒญ์์ ์ฌ๋ฐ๋ฅธ HTTP ์ํ ์ฝ๋๋ฅผ ๋ฐํํ ์ ์์ต๋๋ค. ์คํ ๋ฃจํธ๋ ๋งค๋ ฅ์ ์ด์ง๋ง ๊ด๊ธฐ๋ก ์ด์ด์ง๋๋ค.์ด์ ์คํ ๋๊ตฌ์ธ React๊ฐ ์์ ์ ์ ์ดํ์ง ์์ต๋๋ค. ์ด๋ป๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ป์ ์ ์์ต๋๊น? ๋ ๋๋งํ ๊ตฌ์ฑ ์์๋ฅผ ์ด๋ป๊ฒ ์ ์ ์์ต๋๊น?
์ฌ๊ธฐ์์ ํธ๋กค์ ํ๋ ค๋ ๊ฒ์ ์๋์ง๋ง ์ด ๋ฌธ์ ์ ์์ฒญ์ ํต์ฌ ์ฃผ์ ๊ฐ ์๋ชป ์๋ด๋์ด ์๊ณ React๊ฐ ์ด๋ฅผ ์์ฉํ๊ธฐ ์ํด ์ด๋ค ๊ฒ๋ ๊ตฌํํด์๋ ์ ๋๋ค๊ณ ๊ฐ๋ ฅํ๊ฒ ์๊ฐํฉ๋๋ค. ์ ์ด๋ ์ฌ๊ธฐ์์ ๋ณธ ์ด์ ๋ ์๋๋๋ค. ์๋ . ์ข์ ์ ํ๋ฆฌ์ผ์ด์ ์ํคํ ์ฒ์ ์ผ๋ถ ์ธก๋ฉด์ ๋ช ํํ์ง ์์ผ๋ฉฐ ์น์ ํนํ ์ ๋๋ก ํ๊ธฐ ์ด๋ ต์ต๋๋ค. ์ฐ๋ฆฌ๋ ํธ์ํจ์ ์ํด ์ฐ์ํจ์ ํฌ์ํ๊ธฐ๋ณด๋ค๋ ์ธํฐ๋ท๊ณผ ์น์ ๋ง๋ ์ฐ๋ฆฌ ์กฐ์๋ค์ ์งํ๋ฅผ ๋ฐฐ์ฐ๊ณ ์กด๊ฒฝํด์ผ ํฉ๋๋ค.
์ด๊ฒ์ด React๋ฅผ ํ๋ฅญํ๊ฒ ๋ง๋๋ ์ด์ ์ ๋๋ค. ๋ฐ๋ก ๋ณด๊ธฐ์ ๋๋ค. ์ต๊ณ ์ ์ ๋ง. ๋ณด๊ธฐ๋ง. ฮป
@d4goxn์ ๋์ํ์ง ์์์ผ ํฉ๋๋ค. ๋๋ React๋ฅผ ๋ณด๊ธฐ ๊ณ์ธต ์ด์์ผ๋ก ๋ง๋ค๋ ค๊ณ ํ์ง ์์ผ๋ฉฐ ๋ผ์ฐํ ์ด ์ค์ํ์ง๋ง ๋ชจ๋ ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์ ์ง์ ํ๊ธฐ์๋ ํ์คํ ์ถฉ๋ถํ์ง ์์ต๋๋ค. ๊ตฌ์ฑ ์์/์ปจํ ์ด๋ ์์ค์์ ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์ ์ง์ ํ๋ฉด React๋ฅผ ๋ณด๊ธฐ ๊ณ์ธต ์ด์์ผ๋ก ๋ง๋ค์ง ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ฑ์ ๋ํด ํจ์ฌ ๋ ๋์ ๊ฒฉ๋ฆฌ ๋ฐ ์ํฌํ๋ก๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ๋จ์ํ ์์ ์ ๋จ์ํํ๋ ๊ฒ์ด ์๋๋ผ ํฐ ์์ฉ ํ๋ก๊ทธ๋จ์ด ํ์ํฉ๋๋ค. ๋ด ์ฑ์ 30๊ฐ์ ๊ฒฝ๋ก๊ฐ ์๊ณ ๊ฐ๊ฐ์ ์ฌ์ฉ์ ํ๋กํ ๊ตฌ์ฑ ์์๋ฅผ ์ถ๊ฐํ๊ณ ์ถ๋ค๊ณ ์์ํด ๋ณด์ญ์์ค. ๋ชจ๋ ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์ด ๊ฐ๊ฐ์ ๋ํด ์ง์ ๋ ๊ฒฝ๋ก ๋์์ ๋ฐ๋ผ ํด๋น ๋ฐ์ดํฐ ์ข ์์ฑ์ ์ถ๊ฐํ๋ ค๋ฉด 30๊ฐ์ ๊ฒฝ๋ก๋ฅผ ๊ฑฐ์ณ์ผ ํฉ๋๋ค. ํด๋น ๊ตฌ์ฑ ์์์ ์ปจํ ์ด๋์ ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์ ์ง์ ํ๋ ๊ฒฝ์ฐ ์ํ๋ ์์น์ ๊ตฌ์ฑ ์์๋ฅผ ์ถ๊ฐํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ํ๋ฌ๊ทธ ์ค ํ๋ ์ด์ ๋๋ค. ๋ฟ๋ง ์๋๋ผ ๋ชจ๋ ๊ตฌ์ฑ ์์ ๋ฐ์ดํฐ ์ข ์์ฑ์ ๋ํ ์ฟผ๋ฆฌ๋ฅผ ์ต์ ํํ ์ ์์ต๋๋ค. Relay๊ฐ ์ด์ ๋ํ ์ข์ ์์ด๋ฉฐ ์ด์ ๋ํ ์ด์ผ๊ธฐ๊ฐ ๋๋ณด๋ค ํจ์ฌ ๋ ์ ์ค๋ช ๋ฉ๋๋ค.
๋๋ ์ค๋๋ ์งํ์ ๋ํด ๋ง์ ์กด๊ฒฝ์ฌ์ ๊ฐ์ง๊ณ ์์ง๋ง ๊ทธ๊ฒ์ด ์งํ์ ์๋ก์ด ํ์ค์ ๋ง๋๋ ๋ฐ ํ๊ณ๊ฐ๋์ด์๋ ์๋ฉ๋๋ค. ์ ์ด๋ ๋๋ ๊ทธ๋ ๊ฒ ๋ด ๋๋ค.
๋ด ์ ์์ ๊ธฐ๋ณธ์ ์ผ๋ก React๋ฅผ ๋ณ๊ฒฝํ์ง ์๋ ๊ฒ์ด์ง๋ง dom/components ํธ๋ฆฌ๋ฅผ ๋ณ๊ฒฝํ๋ '๊ฐ์ ์ ์ฉ' ๋ฐฉ๋ฒ, ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฒ ์ธก์์ '์คํ'ํ ์ ์๋ React๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. DOM์ ๋ณ๊ฒฝํ๊ธฐ ์ํด). ์ฌ์ ํ ์บ์ฑ๊ณผ CDN์ด ์์ ์ ์์ต๋๋ค. ์ค๋๋ ์ฌ์ดํธ์ ์์ฉ ํ๋ก๊ทธ๋จ์ ์ญํ์ด ์ฆ๊ฐํจ์ ๋ฐ๋ผ ์ ์ ์บ์ฑ์ด ๊ฐ์ํ๋ ๊ฒฝํฅ์ด ์์ง๋ง ๊ทธ๊ฒ์ ๋ ๋ค๋ฅธ ์ฃผ์ ์ ๋๋ค ๐
๋ณด๊ธฐ๊ฐ ๋ฐ์ดํฐ์ ๋ํ ์ข ์์ฑ์ ์ง์ ํ๋ ๊ฒฝ์ฐ ์ข ์์ฑ ๊ทธ๋ํ๋ฅผ ์ต์ ํํ๊ณ ์ด๋ฅผ ์ต์ํ์ ์ฟผ๋ฆฌ๋ก ๋ณํํ๋ ๋ฐฉ๋ฒ์ด ํ์ํฉ๋๋ค. ๋ณด๊ธฐ๋ฅผ ๊ตฌ์ฑํ๊ธฐ ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ค๋นํ ์๋ ์์ง๋ง ๋ ๋จ๊ณ๋ก ๋๋ ์๋ ์์ต๋๋ค. ์ด๊ฒ์ด ์ด ์ค๋ ๋์ ๊ณํ์ ์ดํดํ๋ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด ๊ฐ๊ฐ ๊ณ ์ ํ ์ฟผ๋ฆฌ๊ฐ ์๋ ์ ๋นํ ๋ณต์กํ ๊ตฌ์ฑ ์์ ๋ชจ์์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์๋ง๋ ๊ทธ๊ฒ๋ค์ ๋์ผํ ๊ตฌ์ฑ ์์์ ๋ชจ๋ ์ธ์คํด์ค๊ฐ ์๋๋ฉฐ ๋จ์ผ ์ฟผ๋ฆฌ๋ก ์ถ์๋ ์ ์๋ ํจํด์ด ์์ต๋๋ค. ์ด๊ฒ์ด GraphQL์ด ํด๊ฒฐํ๊ณ ์ ํ๋ ๋ฌธ์ ๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๊ฐ ๋ฐ์ดํฐ ์ ์ฅ์์ ๋ํด GQL ์๋ฒ๋ฅผ ๊ตฌํํ๊ฑฐ๋ ํตํฉํด์ผ ํฉ๋๋ค. ์ต์ ํ๋ GQL ์ฟผ๋ฆฌ์ ์ด๋ค ๋ถ๋ถ์ ์ด๋ค ๋ฐ์ดํฐ ์ ์ฅ์๋ก ์ฒ๋ฆฌํด์ผ ํ๋์ง ์ ๋ ฌํ๋ ๊ฒ์ ๊ฝค ๋ณต์กํ๊ฒ ๋ค๋ฆฌ์ง๋ง ๋ด ์ ์์๋ ๊ทธ๋ฐ ๋ณต์ก์ฑ์ด ์์ต๋๋ค.
๋ชจ๋ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ํ์๋ก ํ๋ ๋ง์ ์์ ๊ฒฝ๋ก๊ฐ ์๋ ์์์ ์ค์ ๋ก URL์์ ํด๋น ๋ฐ์ดํฐ ์์ค์ ๋ํ ์๋ณ์๋ฅผ ์ ์ธํ๋ ์ด์ ๋ก ๋ณด์ง ์์ ๊ฒ์ ๋๋ค. ์คํ์ ๋ฃจํธ์ ์๋นํ ๊ฐ๊น์ด ์์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋ฏธ๋ค์จ์ด ๋ชจ๋์ ๋ง์ดํธํ๋ฉด ํด๋น ์ฌ์ฉ์ ๊ฐ์ฒด๋ฅผ ์ปจํ ์คํธ์ ์ฐ๊ฒฐํ ๋ค์ ์ปจํ ์คํธ๋ฅผ ๋ ๋ง์ ๋ฏธ๋ค์จ์ด์ ํจ๊ป ์ต์ข ๊ฒฝ๋ก ์ฒ๋ฆฌ๊ธฐ๋ก ์ ๋ฌํฉ๋๋ค. ๋ฃจํธ React ๊ตฌ์ฑ ์์๋ ์ปจํ ์คํธ์ ํน์ ๋ถ๋ถ์ ์ ๊ฒฝ ์ฐ์ง ์์ ์ ์์ง๋ง ๊ทธ๊ฒ์ ๋ํด ๊ด์ฌ์ ๊ฐ์ง ์ ์๋ ๋ค์ ์์ค์ ์์์๊ฒ ์ ๋ฌํ๊ฑฐ๋ ์์ ์ ํ์์ด ๊ด์ฌ์ ๊ฐ์ง ์ ์๋๋ก ์ ๋ฌํฉ๋๋ค. ์ด๊ฒ์ด ๋ถ๋นํ๊ฒ ๋ณต์กํ๊ฑฐ๋ ๊น์ ๋ฐฐ์ ์ ๋์ ํ๋ฉด Flux ์ ์ฅ์์ ๊ฐ์ ๊ฒ์ด ํ์ํ ์ ์์ง๋ง ๊ทธ ์์ฒด๋ก ํฐ ์ฃผ์ ์ ๋๋ค.
๋ถ๋ฆฌ์ ๊ณ ๋ฆฝ: ๊ทธ๊ณณ์์ ๋น์ ์ ๊ณ ํต์ ๋๋๋๋ค. ๋ด ์ ์์์ ์ฐ๋ฆฌ๋ ์ ์ฅ ๋ฐ ๊ฒ์์ ์ต์ ํ๋ ํ์์์ ์ถ์์ ์ธ ๋จ์์ฑ์ ์ต์ ํ๋ ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณํํ๋ ๋ ๊ฐ์ ๋งค์ฐ ๋ค๋ฅธ ์์คํ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ด ๊ฒฌํด๋ ๊ตฌ์ฑ ์์ ๊ณ์ธต ๊ตฌ์กฐ๋ก ์ ๋ฌ๋จ์ ๋ฐ๋ผ ๊ทธ๊ฒ์ ์ ํฉํ ํ์์ผ๋ก ๋ณํํ๋ ๊ฒ์ ๋๋ค. ๋ ์์คํ ์ ์ถ๊ฐํด์ผ ํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ฉด์ ๋ ์์คํ ์ ๋์จํ๊ฒ ์ฐ๊ฒฐํ ์ํ๋ก ์ ์งํ๋ ๊ฒ์ ์ ๊ฐ ์ด๋ ค์ด ์ผ์ด ์๋์ง๋ง ์ ํญ์ด ๊ฐ์ฅ ์ ์ ๊ฒฝ๋ก๋ ์๋๋๋ค. ๋ฐ์ดํฐ ์ ์ฅ์๋ฅผ ์ํ ํ๋ก๊ทธ๋๋ฐ๊ณผ ๋์ UI๋ฅผ ์ํ ํ๋ก๊ทธ๋๋ฐ ์ฌ์ด์ ์ ์ ์ ์ ํ์ ํ์ค์ ๋๋ค. ์ฐ๋ฆฌ๋ ๋ณ๋์ ๋ฐฑ์๋ ๋ฐ ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ฅผ ๊ฐ๊ณ ์์๊ณ HTTP๋ ์ด ๋ ํจ๋ฌ๋ค์ ์ฌ์ด์ ์ธํฐํ์ด์ค ์ญํ ์ ํ์ต๋๋ค. ์ด์ ๋๋ ๊ทธ๊ฒ์ ํ๋์ ์์ฉ ํ๋ก๊ทธ๋จ์ผ๋ก ๋ด๋ถํํ๋ ค๊ณ ์๋ํ๊ณ ์์ผ๋ฉฐ ๋น์ ์ ๊ทธ๊ฒ์ ์์ํ๋ ค๊ณ ํฉ๋๋ค.
๋๋ ์ ํ๋ฆฌ์ผ์ด์ ๋ด์์ ์ฆ๊ฐํ๋ ๋ณต์ก์ฑ๊ณผ ํ๋์ผ๋ก ์ธํด ํด๋ผ์ด์ธํธ ์ํ๊ฐ ์๋ฒ์ ํจ์ฌ ๋ ํฐ ๋ฐ์ดํฐ ์ธํธ๋ฅผ ์ฐธ์กฐํ๋ ๋งค์ฐ ์์ ๊ฐ์ฒด๋ก ํํ๋๋ ๊ฒ์ ๋ฐฐ์ ํ ์ ์๋ค๊ณ ํ์ ํ์ง ์์ต๋๋ค. ๋๊ท๋ชจ ๋ฉํฐํ๋ ์ด์ด 1์ธ์นญ ์ํ ๊ฒ์์ ์๊ฐํด ๋ณด์ญ์์ค. ๋ง์ ์ผ์ด ๋น ๋ฅด๊ฒ ์งํ๋๊ณ ์์ผ๋ฉฐ ํด๋ผ์ด์ธํธ์์ ๊ฒ์ ํธ์คํธ/์๋ฒ๋ก ํ์ํ ์ต์ํ์ ์ ๋ณด๋ฅผ ์ ์กํ๋ ค๊ณ ํฉ๋๋ค. ์ผ๋ง๋ ์์ ๊ฒ์ ์ป์ ์ ์์์ต๋๊น? ๋ชจ๋ ์ ๋ ฅ ์ํ์ ๋งต. ํ์์คํฌํ + ๋ถํ์ค์ฑ ๋ฒ์, ํค๋ณด๋์ฉ ~110๋นํธ ํ๋, ๋ง์ฐ์ค/์กฐ์ด์คํฑ ๋ฐ VR ํค๋์ ๋ฐฉํฅ์ฉ ์์ญ ๋ฐ์ดํธ. ํด๋ผ์ด์ธํธ๋ ์์ธกํ๊ณ , ๋๊ด์ ์ผ๋ก ๋ ๋๋ง ๋ฐ ๋ฌผ๋ฆฌ์ ์ฒ๋ฆฌํ๊ณ , ์๋ฒ๋ ํด๋ผ์ด์ธํธ์ ์์ ์ํ ๋ฐ ์ํ ๊ธฐ๋ก์์ ์์ฒญ๋ ์์ ์ ๋ณด๋ฅผ ๋์ถํ๊ณ ๋ชจ๋ ํด๋ผ์ด์ธํธ๋ฅผ ์์ ํ๊ณ ์ ๋ฐ์ดํธํ๊ธฐ ์ํด ์๋นํ ๋ง์ ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํฉ๋๋ค( ๋ชจ๋ ์ฃผ๋ณ ์์ด์ ํธ์ ๋ํด ๋์ผํ ๋งค๊ฐ๋ณ์, ์์ฐ ํธ์), ๊ทธ๋ฌ๋ ํด๋ผ์ด์ธํธ ์์ฒญ ์คํธ๋ฆผ์ ์ฌ์ ํ โโ2KB ์์ฒญ์ ์ ํฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ํคํ ์ฒ์ ๋์์ด ๋ ์ ์์ต๋๋ค.
Relay์ GraphQL์ ๋ํ ๊ต์ก์ ์์ฒญํ์ง ์์ต๋๋ค. API๊ฐ ์์ ์ ์ธ ๋ฒ์ ์ ๋๋ฌํ๊ธฐ ์ ์ ํผ์์ ์ผ๋ก๋ง ์ดํด๋ณด์์ ๋ฟ์ ๋๋ค(์ง๊ธ ์ ๊ฒจ ์์ต๋๊น?) ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ์ข ์์ฑ์ ์ง์ ํ๊ณ ๊ฐ์ ธ์์ผ ํ ์ค์ ๋ฐ์ดํฐ๋ฅผ ๊ฒฐ์ ํ๋ GraphQL ์คํค๋ง๋ฅผ ์ ํํ๋ ๊ฒ์ด ์ฌ์ ํ ํ์คํ๋ค๋ฉด, ์ข์ ๊ณํ์ ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ๋ค์ ํ ๋ฒ ์ดํด๋ด์ผ ํ ๋์ผ ๊ฒ์ ๋๋ค. ๊ทธ ์ํคํ ์ฒ์ ๋ํด ๋ช ๊ฐ์ง ์ด๋ ค์ด ์ง๋ฌธ์ด ์์ง๋ง ์ฃผ์ ์์ ๋ฒ์ด๋๋ ค๊ณ ํฉ๋๋ค.
:๋งฅ์ฃผ:
์ถ์ : HTTP๊ฐ MMOFPS๋ฅผ ์ํ ์ข์ ํต์ ํ๋กํ ์ฝ์ด ๋ ๊ฒ์ด๋ผ๊ณ ์ ์ํ๋ ค๋ ๊ฒ์ ์๋๋๋ค.
@d4goxn ์ด์ ๋ํ ๊ทํ์ ๋ง์ค์๊ณผ ํ์๋ฅผ
๋๋ ์ด ์์ค์ ์ถ์ํ๊ฐ ๊ฐ ๊ธธ์ด๋ผ๊ณ ๋ฏฟ์ต๋๋ค. ๋๋ Relax CMS์์ ๊ทธ๊ฒ์ ์ฌ์ฉํด ์์ผ๋ฉฐ ์ํฌํ๋ก์ฐ์ ๊ฒฉ๋ฆฌ๋ ํจ๊ป ์ผํ ์ ์๋ ํ๋ณต์ ๋๋ค. ๋ฟ๋ง ์๋๋ผ ์์ฒญ๋ ๋ฐ์ดํฐ๋ ui๊ฐ ํ์๋ก ํ๋ ๊ฒ ์ด์๋ ์ดํ๋ ์๋๋ฉฐ ๊ฐ ๊ตฌ์ฑ ์์์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ๋ณํฉํ์ฌ ์๋์ผ๋ก ๋ง๋ค์ด์ง๋๋ค. ์ด๊ฒ์ ํ์ธ์ ๊ด์ฌ์ด ์๋ ๊ฒฝ์ฐ Relate http://relax.github.io/relate/how-it-works.html ์์ ์ํํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ด ์์ฉ ํ๋ก๊ทธ๋จ์ ๋ชจ๋ ๊ตฌ์ฑ ์์๋ฅผ ํฌํจํ ์ ์์ผ๋ฉฐ ๋ด ์์ฉ ํ๋ก๊ทธ๋จ์ ๋ ๋ฆฝ์ ์ธ ๋ธ๋ก์ผ๋ก ์๋ํ๋์ง ํ์ธํ ์ ์์ต๋๋ค.
์์ง ํ์ ํด์ผ ํ ์ ์ผํ ๊ฒ์ ์๋ฒ ์ธก ๋ ๋๋ง์ ๋๋ค. ๋ฐ์์ ์์ค ์ฝ๋๋ฅผ ์ดํด๋ณธ ํ ๋ด๊ฐ ์ค๋ช ํ ๋๋ก ์ด๋ฏธ ์๋ฃจ์ ์ด ์์ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ๋ฐ์ ํ์ ๋๊ตฐ๊ฐ๊ฐ ์ด์ ๋์ํ๋ฉด ์๋ฃจ์ ์ ์์ ํ ์ ์์ต๋๋ค.
@d4goxn ๋๋ ๊ฐํ ๋น์ ๊ณผ ๋ ผ์ํ ๊ฒ์ ๋๋ค :) ๋น์ ์ ์๋ ๊ฒ์๋ฌผ์๋ ๋ณด๊ธฐ๊ฐ ๋ฐ์ดํฐ์ ํจ์์ด๊ณ ๋ฐ์ดํฐ๊ฐ URL์ ํจ์ ๋ผ๋ ์ง์ ์ด ํฌํจ๋์ด ์์ต๋๋ค. ๋๋ ์ด๊ฒ์ ์ ํํ ๊ณต๊ฐ๋ผ๊ณ ๋ถ๋ฅด์ง ์์ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ ์์ ํ ์์์ ์ด์ง ์์ ๋ชจ๋ ์น ์ฌ์ดํธ ๋๋ ์น ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ฑฐ์ ์ ์ฉ๋ฉ๋๋ค(์๋ฅผ ๋ค์ด ์ด๋ฆฐ ๋ํ ์์ ์ฐฝ์ ์ํ๋ URL์ ์ผ๋ถ์ฌ์ผ ํ๋์ง ์ฌ๋ถ์ ๋ํ ์ง๋ฌธ์ด ์์ต๋๋ค). ์ฐ๋ฆฌ ๋ชจ๋๋ ํ๊ต์์ ์ํ์ ํ์ผ๋ฏ๋ก ํจ์๊ฐ ๊ตฌ์ฑ๋ ์ ์์์ ์๋๋ค. ๋ฐ๋ผ์ ์ค์ ๋ฌธ์ฅ์ ํ๋ฉด์ ๋ณด์ด๋ ๊ฒ์ด URL์ ํจ์ ๋ผ๋ ๊ฒ์ผ ์ ์์ต๋๋ค. ๋ค์ ๋งํ์ง๋ง, ์ค์ ๋ก ๋ฐํ์ง ๊ฒ์ ์์ผ๋ฉฐ, ๋จ์ง ๋ช ๋ฐฑํ ๊ฒ์ ํ์ํ์ผ ๋ฟ์ ๋๋ค.
๋์๊ฒ ์ฃผ์ ์ง๋ฌธ์ ๊ทธ๋ฌํ ๊ธฐ๋ฅ์ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ ์ ๋๋ค.
๋น์ ์ด ์ ์ํ ์ ๊ทผ ๋ฐฉ์์ ์ข์ ์ค๋๋ ์๋ฒ ์ธก MVC ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๋งค์ฐ ์ ์ฌํฉ๋๋ค(์: Spring MVC๊ฐ ์ข์ ์์ ๋๋ค). ํ์ฌ URL์ _๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๋ ํด๋น ์ปจํธ๋กค๋ฌ ๋ฉ์๋๋ฅผ ํ์ฑํํฉ๋๋ค. ํ์ํ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ๋ทฐ์ ์ ๋ฌํฉ๋๋ค. ์ด์ ๋ํ ๋ด ๋ฌธ์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์์ฑ๋ ์น ํ์ด์ง๋ฅผ ๋ณด๋ฉด ์ผ์ข ์ ๊ตฌ์ฑ ์์ ๊ณ์ธต ๊ตฌ์กฐ์ ๋๋ค(๋ฐ๋์ React ๊ตฌ์ฑ ์์๋ ์๋). ๋น์ ์ด ํด์ผ ํ ์ผ์ URL์์ ๊ณ์ธต์ ์์ฑํ๊ฑฐ๋ ์์ฑํ๋ ๊ฒ์ ๋๋ค. ํ์ง๋ง ๋ ๋ฒ ํด์ผ ํฉ๋๋ค! ์ฒซ์งธ, ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ผ ํ๋์ง ์๊ธฐ ์ํด ์ปจํธ๋กค๋ฌ์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๋์ฝ๋ฉํด์ผ ํ๊ณ , ๋ ๋ฒ์งธ๋ก ๋ณด๊ธฐ์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๋์ฝ๋ฉํ์ฌ... ์... ์ค์ ๋ณด๊ธฐ๋ฅผ ๋ ๋๋งํด์ผ ํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ๋งค์ฐ _DRY_ ์ ๊ทผ ๋ฐฉ์์ด๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค.
์ ๋ Spring MVC์ ์ต์ํ์ง ์์ง๋ง React๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๊ณผ ๋งค์ฐ ์ ์ฌํ ๋ฐฉ์์ผ๋ก ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ ๋ค๋ฅธ MVC ํ๋ ์์ํฌ(Nette๋ผ๊ณ ํ๋ PHP ํ๋ ์์ํฌ)๋ฅผ ์์ฃผ ์ฌ์ฉํฉ๋๋ค. ์ด ํ๋ ์์ํฌ๋ ๊ตฌ์ฑ ์์๋ ์ง์ํฉ๋๋ค. ์์ด๋์ด๋ ๊ฐ ๊ตฌ์ฑ ์์(์: ์์)์ ๋ํด ๊ตฌ์ฑ ์์๋ฅผ ์ธ์คํด์คํํ๊ณ ํนํ _ํ์ํ ๋ชจ๋ ๋ฐ์ดํฐ ๋ก๋_๋ฅผ ๋ด๋นํ๋ ํฉํ ๋ฆฌ๋ฅผ ์ฝ๋์ ์ ์ํ๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ด๋ฌํ ๊ตฌ์ฑ ์์๋ ๋ณด๊ธฐ์ ์ด๋ ์์น์๋ ํฌํจ๋ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ HTML ์ฝ๋๋ฅผ ์์ฑํ๊ณ _view ๊ณ์ธต ๊ตฌ์กฐ_๋ฅผ ์์ฑํ ๋ ๊ตฌ์ฑ ์์๋ฅผ ์ฝ์ ํ๊ธฐ๋ง ํ๋ฉด ๊ธฐ๋ณธ ํฉํ ๋ฆฌ๊ฐ ํ์ํ ์ด๊ธฐํ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. ๊ตฌ์ฑ ์์๋ ์์ ๋ ๋ฆฝ ์ปจํธ๋กค๋ฌ์ฒ๋ผ ์๋ํ๊ณ ์์ฒด ์๋ช ์ฃผ๊ธฐ๊ฐ ์์ผ๋ฉฐ ์ข ์์ฑ์ ์ฒ๋ฆฌํ๊ณ ๋ทฐ์์ ๋งค๊ฐ๋ณ์ํํ์ฌ ์ฌ์ฌ์ฉ์ฑ์ ๋์ผ ์๋ ์์ต๋๋ค.
ํด๋ผ์ด์ธํธ ์ธก์์๋ React์ ํจ๊ป ์ด ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํด ์์ผ๋ฉฐ ๋งค์ฐ ์คํ ๊ฐ๋ฅํ ๊ฒ ๊ฐ์ต๋๋ค. React ๊ตฌ์ฑ ์์๋ ์ฒ์๋ถํฐ _controller-views_๋ก ํ์๋์ด ์์ผ๋ฉฐ ๊ทธ๋ ๊ฒ ์ฌ์ฉํฉ๋๋ค. ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๋ด๋นํ๋ _controller_ ๊ตฌ์ฑ ์์๊ฐ ์๊ณ ์๊ฐ์ ๊ฐ์ฒด์๋ง ๊ด์ฌ์ด ์๋ _view_ ๊ตฌ์ฑ ์์๊ฐ ์์ต๋๋ค. ์ ์ฒด ํ์ด์ง๋ ๋ ๊ฐ์ง ์ ํ์ ๊ตฌ์ฑ ์์๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ๊ทธ๋ค์ ๋ฉ์ง๊ฒ ๋ถ๋ฆฌ๋์ด ์ฝ๊ฒ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ด ์์ฉ ํ๋ก๊ทธ๋จ์ ํ์ํ์ง ์์๊ธฐ ๋๋ฌธ์ ๋ํ(๋๋ ์ค๋๋ ๊ทธ๋ค์ด ๋ถ๋ฅด๋ ๋ณดํธ์ )์ด ์๋์ง๋ง ๋ด๊ฐ ์ฌ์ฉํ๋ ์คํ์ ๊ทธ๋ ๊ฒ ํ ์ ์์ด์ผ ํฉ๋๋ค(์์ง ์คํ์ ์ธ Relay๋ฅผ ์ ์ธํ๊ณ ์ด ์คํ์ ์ด ๋ฌธ์ ์์ ๊ฐ์ฅ ๊ธด ๊ฒฝ๋ก). ์ฐธ๊ณ ๋ก ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
react-router
์ ๋์์ธ์
๋๋ค. ๋์ผํ ์์น์์ _data-hierarchy_ ๋ฐ _view/component hierarchy_๋ฅผ ๋ชจ๋ ์ ์ํ ์ ์์ผ๋ฉฐ ์ค์ ๊ฒฝ๋ก ์ ์๋ ๊ณ์ธต์ ์
๋๋ค. ๊ทธ๊ฒ์ ๋งค์ฐ _๋ฐ์ํ๋ ๊ฒ ๊ฐ์_ ๋๋์
๋๋ค.connect()
์ ๊ทผ ๋ฐฉ์ ๋๋ถ์ props๋ฅผ ์ฌ์ฉํ์ฌ ์ต์์ ์์ค์์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์๋๋ก ์ ๋ฌํ ํ์๊ฐ ์์ต๋๋ค.์์ง ์๋ฒฝํ์ง๋ ์์ง๋ง ์ด ์ค๋ ๋๋ฅผ ์ฒ์ ์ ํ์ ๋ ์ฌ์ฉํ ์ ์์๋ ๊ฒ๋ณด๋ค ์๋นํ ์ง์ ์ด ์์ต๋๋ค. ์ํ ๊ตฌํ์ ์ฌ๊ธฐ ์์ ์ฐพ์ ์
๋ ์ญ์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๊ฐ ๊ตฌ์ฑ ์์ ์์ค์ ์์ ๋ ์๋ฒ ์ธก ๋ ๋๋ง์ ์ํํ๋ ๋ฐฉ๋ฒ์ด ํ์ํ ๊ฒ์ ์ ์ธํ๊ณ ๋ ๊ฑฐ์ ๋ชจ๋ ๋ํ ์์ ์ ์ํํฉ๋๋ค. ์ง๊ธ ๋น์ฅ์ ์ฒ ํ์ ๋ ผ์์ ์ถ๊ฐํ์ง ์๊ณ , ๋๋ componentDidMount์์ ์์ ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ตฌ์ฑ ์์์ ํจ๊ป ๋ฐ๋๋ผ ๋ฐ์(๋ํ ์์ฒด ๊ฐ๋ฐ ๋ผ์ฐํ )์ ์ฑ๊ณต์ ์ผ๋ก ์ฌ์ฉํด ์์ต๋๋ค. ๋ด ๊ตฌ์ฑ ์์ ๋ฐ ๋ฐ์ดํฐ ์ข ์์ฑ์ ์ ์ํ๊ธฐ ์ํด ์ค๋ณต ๊ตฌ์กฐ๋ฅผ ์ ์งํ๋ ์์ด๋์ด๊ฐ ์ ๋ง ์ซ์ต๋๋ค. ๋ด ๊ตฌ์ฑ ์์ ํธ๋ฆฌ์ ์ด๋ฏธ ์ ์๋์ด ์์ผ๋ฉฐ ์ฌ๊ธฐ์์๋ ์ ์ฒด ๊ตฌ์ฑ ์์๊ฐ ์๋ฃ๋ ๋๊น์ง ๋น๋๊ธฐ์ ์ผ๋ก ๊ฐ์ ธ์ฌ ๋ ๋ฐ์ดํฐ๋ฅผ ํตํฉํ๋ ์ฌ๋ฌ ๋ ๋ ํจ์ค๊ฐ ํ์ํ ์ ์์ต๋๋ค. ํธ๋ฆฌ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค.
๋ฐ๋ก ์ง๊ธ, ๋๋ isomophic react, imo์ ๋ํ ์ด๊ฒ์ ์ค์์ฑ์ด ์ปค์ง๊ณ ์๋ค๋ ๊ฒ์ ๋ ๋ฒ์งธ๋ก ๋งํ๊ณ ์ถ์์ต๋๋ค. ๋๋ ๊ทธ ๋์ ํด๊ฒฐ์ฑ ์ ์ฐพ์ผ๋ ค๊ณ ๋ ธ๋ ฅํ ๊ฒ์ ๋๋ค. ๊ฐ์ฌ ํด์.
๊ด์ฌ์ด ์๋ ๊ฒฝ์ฐ ํธ๋๋ฒ์๋ฅผ ์ํํ์ต๋๋ค. -dependencies.js. ์ด๋ ๊ฒํ๋ฉด ๋ชจ๋ ๋ฐ์ดํฐ ์ข ์์ฑ์ ์ป์ ์ ์์ต๋๋ค -> ๋ฐ์ดํฐ ๊ฐ์ ธ ์ค๊ธฐ -> ๋ฐ์ ๋ ๋๋ง์ ๋ฌธ์์ด๋ก.
@decodeman , FWIW์์๋ ๋๊ท๋ชจ ํ๋ก๋์
์ฑ์์ ์ด์ค ๋ ๋ ์ ๊ทผ ๋ฐฉ์(๊ทํ๊ฐ ์ธ๊ธํ ๊ฒ๊ณผ ๊ฐ์)์ ์ฑ๊ณต์ ์ผ๋ก ์ฌ์ฉํด ์์ต๋๋ค. ์ด redux-saga ์์ ์์ ์๊ฐ์ ์ป์์ง๋ง ์ผ๋ฐ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ๋ชจ๋ ์ ํ์ ๋น๋๊ธฐ ๋ก๋ฉ์์ ์ ์๋ํด์ผ ํฉ๋๋ค. ๋ก๋๋ฅผ componentWillMount
๋ก ์ด๋ํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ๊ด๋ฆฌ ์ฉ์ด์ฑ์ ์ ์งํ๊ธฐ ์ํด ์ผ๋ฐ์ ์ธ ๋ก๋ ์๋๋ฆฌ์ค๋ฅผ ์ฒ๋ฆฌํ๋ ๊ณ ์ฐจ ๊ตฌ์ฑ ์์๋ ์์ต๋๋ค(์: prop x
ํ๊ณ nil์ด๋ฉด ๋ก๋ํฉ๋๋ค.
๋ํ ๊ตฌ์ฑ ์์ ๋ด์์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ ์ ์๊ณ ์ผ์ข
์ ์ง์ฐ ๋ ๋๋ง ๋ฐฉ๋ฒ์ ๊ฐ๋ ๊ฒ์ด ๋งค์ฐ ์ค์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์์ชฝ ๋ชจ๋๋ฅผ ํ๋ณตํ๊ฒ ํ๊ธฐ ์ํด asyncRenderToString์ด๋ผ๋ ์ ๋ฉ์๋๋ฅผ ๋ง๋ค๊ณ asyncOnLoad
๋๋ ์ด์ ์ ์ฌํ ์๋ก์ด "lifecycle" ์ด๋ฒคํธ๋ฅผ ์ถ๊ฐํฉ๋๋ค. asyncRender ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒฝ์ฐ์๋ง ํธ์ถ๋ฉ๋๋ค. ์๋ฒ ์ธก๊ณผ ํด๋ผ์ด์ธํธ ์ธก ์ฌ์ด์ ์ฝ๋ ์ค๋ณต ์ธก๋ฉด์์ ์ด๊ฒ์ ๊ฐ๋ฐ์๊ฐ ์ผ๋ฐ์ ์ธ ๋ก๋ฉ ์ฝ๋๋ฅผ ๋ณ๋์ ๋ฉ์๋๋ก ์ฎ๊ธฐ๊ณ asyncOnLoad
๋ฐ componentMount
์์ ํด๋น ๋ฉ์๋๋ฅผ ํธ์ถํจ์ผ๋ก์จ ์์ ํ ์ ์์ต๋๋ค. asyncOnLoad๊ฐ ์๋ฃ๋์๋์ง ๊ฐ์งํ๋ฉด ๋ฐํ๋ Promise๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค(undefined๊ฐ ๋ฐํ๋๊ฑฐ๋ ๋ฉ์๋๊ฐ ์ ์๋์ง ์์ ๊ฒฝ์ฐ ํด๋น ์๋ช
์ฃผ๊ธฐ ์ด๋ฒคํธ๋ฅผ ์ง์ ํธ์ถํ ๋ค์ ๋ ๋๋งํด์ผ ํจ). ๊ทธ๋ ์ง ์์ผ๋ฉด Promise๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค.
๊ทธ๋ฐ ์๋ฃจ์ ์ด ์ ์ ํ ์๋ฒ ์ธก ๋ ๋๋ง์ ์ํด ํ์ฌ ์ฌ์ฉํด์ผ ํ๋ ๋ชจ๋ ํดํน ๋ฐฉ๋ฒ์ ํด๊ฒฐํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋ฐ์ ๋ผ์ฐํฐ v4๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ ์์ฉ ํ๋ก๊ทธ๋จ์ ์ฌ์ด ์๋ฒ ์ธก ๋ ๋๋ง ํ์ฉ(์ด๋ ํ์ฌ ๋ํ ์์ฉ ํ๋ก๊ทธ๋จ์ ์๋์ํค๋ ์ ์ผํ ๋ฐฉ๋ฒ์ธ ์ค์ ๊ฒฝ๋ก ๊ตฌ์ฑ์ ๋ ์ด์ ์ฌ์ฉํ์ง ์์)
์ด๊ฒ์ ์คํธ๋ฆผ ์ฒดํฌ ์์ ๋ฐ์ ์คํธ๋ฆผ์ด๋ผ๊ณ ํ๋ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค.
2016๋
11์ 3์ผ ๋ชฉ์์ผ, Florian Krauthan [email protected]
์ผ๋ค:
๋ด์์ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ ์ ์๋ ๊ฒ๋ ๋งค์ฐ ์ค์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ตฌ์ฑ ์์์ ์ผ์ข ์ ์ง์ฐ ๋ ๋๋ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์๋ง๋ ๋ ๋ค ๋ง๋ค๊ธฐ ์ํด
side happy๋ asyncRenderToString์ด๋ผ๋ ์ ๋ฉ์๋๋ฅผ ๋ง๋ค๊ณ ์ ๋ฉ์๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.
asyncOnLoad ๋๋ ์ด์ ์ ์ฌํ "lifecycle" ์ด๋ฒคํธ. ์ด๊ฒ์
asyncRender ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒฝ์ฐ์๋ง ํธ์ถ๋ฉ๋๋ค. ์ฝ๋ ๋ฉด์์
์๋ฒ์ ํด๋ผ์ด์ธํธ ์ธก ๊ฐ์ ์ค๋ณต์ ๊ฐ๋ฐ์๊ฐ ์์ ํ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ธ ๋ก๋ฉ ์ฝ๋๋ฅผ ๋ณ๋์ ๋ฉ์๋๋ก ์ฎ๊ธฐ๊ณ
asyncOnLoad ๋ฐ componentMount์ ๋ฉ์๋์ ๋๋ค. asyncOnLoad์ธ์ง ๊ฐ์ง
done์ ๋ฐํ๋ Promise๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค(undefined๊ฐ
๋ฐํ๋/์ ์๋์ง ์์ ๋ฉ์๋๋ ํด๋น ํญ๋ชฉ์ ์ง์ ํธ์ถํด์ผ ํฉ๋๋ค.
์๋ช ์ฃผ๊ธฐ ์ด๋ฒคํธ ๋ฐ ๋ ๋๋ง) ๊ทธ๋ ์ง ์์ผ๋ฉด ์ฝ์ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค.
ํด๊ฒฐํฉ๋๋ค.๊ทธ๋ฐ ์๋ฃจ์ ์ด ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํด์ผ ํ๋ ๋ชจ๋ ํดํน ๋ฐฉ๋ฒ์ ํด๊ฒฐํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
ํ์ฌ ์ ์ ํ ์๋ฒ ์ธก ๋ ๋๋ง์ ์ํด. ์๋ฅผ ๋ค์ด ํ์ฉ
๋ฐ์ ๋ผ์ฐํฐ v4๋ก ๋ฐ์ ์์ฉ ํ๋ก๊ทธ๋จ์ ์ฌ์ด ์๋ฒ ์ธก ๋ ๋๋ง
(์ง๊ธ์ ์ค์ ์ง์ค์ ๊ฒฝ๋ก ๊ตฌ์ฑ์ ๋ ์ด์ ์ฌ์ฉํ์ง ์์ต๋๋ค.
๋ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋์ํค๋ ์ ์ผํ ๋ฐฉ๋ฒ)โ
์ด ์ค๋ ๋์ ๊ฐ์ ํ๊ธฐ ๋๋ฌธ์ ์ด ๋ฉ์์ง๋ฅผ ๋ฐ๊ณ ์์ต๋๋ค.
์ด ์ด๋ฉ์ผ์ ์ง์ ๋ต์ฅํ๊ณ GitHub์์ ํ์ธํ์ธ์.
https://github.com/facebook/react/issues/1739#issuecomment -258198533,
๋๋ ์ค๋ ๋ ์์๊ฑฐ
https://github.com/notifications/unsubscribe-auth/ATnWLUIEJw4m1Y3A4oGDOBzP6_ajDcqIks5q6g4_gaJpZM4CHAWq
.
@yamat124 ๋ฐ์ ์คํธ๋ฆผ์ ๊ฒ์ํ๋ฉด ์ด ํ๋ก์ ํธ๋ง ์ฐพ์ต๋๋ค: https://github.com/aickin/react-dom-stream
์ ์ด๋ ๋ฌธ์์ ๋ฐ๋ฅด๋ฉด Promise๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ํ์ ์์์ ๋ํ ๋ค์ ๋ ๋๋ง ํธ์ถ์ ์ง์ฐ์ํค๋ ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ก๋ํ๊ธฐ ์ํ ์๋ช ์ฃผ๊ธฐ ์ด๋ฒคํธ๋ฅผ ๊ฐ์ง ์ ์๋ ๋ฐฉ๋ฒ์ ์์ต๋๋ค. ์๋๋ฉด ๋ค๋ฅธ ๊ฒ์ ๋ง์ํ์๋ ๊ฑด๊ฐ์?
๋ค์ ๋งํ์ง๋ง ๊ทธ๊ฒ์ ๋ชจ๋ ๋งค์ฐ ํดํน๋ ๋ฐฉ๋ฒ์ ๋๋ค. ๊ตฌ์ฑ ์์ ํธ๋ฆฌ์ ๋ ๋ฆฝ์ ์ธ ๋ผ์ฐํ ์ด ํ์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฒฝ๋ก์ ํฌํจ๋ "๋ฉ์ธ" ๊ตฌ์ฑ ์์๋ ๋ก๋ํด์ผ ํ๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์์์ผ ํฉ๋๋ค(์๊ฐ์ 99% ์๋ํ์ง๋ง ํญ์ ๊ทธ๋ฐ ๊ฒ์ ์๋). ๋ฐ์์ ์ง์ฐ๋ ๊ตฌ์ฑ ์์ ๋ ๋๋ง์ด ์๋ ๊ฒฝ์ฐ ๋ ๋ค ๋ ์ด์ ์ฌ์ฉ๋์ง ์์ต๋๋ค.
๋์ํฉ๋๋ค. ์ด๊ฒ์ ์๋ง๋ ์ง๊ธ ๋ฐ์์ ๋ํด ๊ฐ์ฅ ์ซ์ดํ๋ ๊ฒ์ ๋๋ค. ์ฌ๋๋ค์ด ์๋์ผ๋ก ์ํํ ์ ์์ผ๋ฉฐ ์ํํธ์จ์ด ๊ฐ๋ฐ๊ณผ ๊ด๋ จ๋ ๋ชจ๋ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ํ ์ ์๋ค๊ณ ๋งํจ์ผ๋ก์จ ์ด ๊ธฐ๋ฅ์ด ์๋ ํ๋ ์์ํฌ๋ฅผ ๋ฐฉ์ดํ๋ ค๊ณ ํ๋ฉด ์ซ์ดํฉ๋๋ค. ํ์ง๋ง ๊ทธ๋ ๋ค๊ณ ํด์ ๋ฐ๋์ ๊ทธ๋์ผ ํ๋ ๊ฒ์ ์๋๋๋ค. ์ด ์ ํํ ๊ฒ์ด ํ๋ ์์ํฌ ์์ฒด ๋ด์์ ํด๊ฒฐ๋์ด์ผ ํ๋ ๊ฒ ์์ฒด๋ฅผ ์ง์ ํด์ผ ํ๋ ๊ฒฝ์ฐ ์ฒ๋ฆฌํ๋ ์๋ง์ ๋ชจ๋์ด ์๋ค๋ ์ฌ์ค์ ๋๋ค.
Next.js ์๋ ์๋ฒ ์ธก ๋ ๋๋ง์ ์ํํ๊ธฐ ์ํ async getInitialProps
๊ฐ ์์ต๋๋ค. ๋ถํํ๋ ์ฌ์ ํ ๋ถ๋ชจ๋ก๋ถํฐ ๋ฃจํธ๊น์ง ๋ค์ ์์์ getInitialProps
๋ฅผ ํธ์ถ ํด์ผ ํฉ๋๋ค. Apollo GraphQL ํด๋ผ์ด์ธํธ๋ ๋ํ ๋ชจ๋ ํธ๋ฆฌ๋ฅผ ํ์ํ์ฌ ์๋ฒ ์ธก์์ ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์ ์์งํ ๋ค์ ๋ชจ๋ ๊ฒ์ ๋ค์ ๋ณด๋ผ ์ ์์ต๋๋ค. ๋ค์ + Apollo์ ์: https://github.com/sedubois/realate.
์ด๋ฌํ ๊ฒ๋ค์ ํจ๊ป ๊ฒฐํฉํ๊ธฐ ์ํด ๋น๋๊ธฐ React ๊ตฌ์ฑ ์์ ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๊ฐ ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
์ด๋ฒ ์ฃผ์ SSR์ ๋ํด ๋ฐฐ์ ์ต๋๋ค. ์ ๊ฐ ์์ฑํ ๋ด์ฉ์ด ์๋ฏธ๊ฐ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค ๐
/cc @nkzawa @stubailo
BTW componentWill/DidMount
๋ ์ด๋ฏธ ๋น๋๊ธฐ์์
๋๋ค. ๋์์ด ๋๋์?
@sedubois ๋ ๋ ๋๋งํ๊ธฐ ์ ์ React๊ฐ ์ฝ์์ด ํด๊ฒฐ๋๊ธฐ๋ฅผ ๊ธฐ๋ค
@olalonde ๊ทธ๋ ๊ฒ ๋ณด์ ๋๋ค : https://github.com/sedubois/react-async-poc/blob/1d41b6f77e789c4e0e9623ba1c54f5ed8d6b9912/src/App.js
const getMessage = async () => new Promise((resolve) => {
setTimeout(() => {
resolve('Got async message!');
}, 3000);
});
class App extends Component {
state = {
message: 'Loading...',
};
async componentWillMount() {
this.setState({ message: await getMessage() });
}
render() {
return (... {this.state.message} ...);
}
}
@sedubois ๊ทํ์ ์์์ componentWillMount
async componentWillMount() {
this.setState({ message: await getMessage() });
}
๋ฐํ ์ฝ์ํ์ง๋ง, ์คํฌ๋ฆฐ ์ท๋ ๋ ๋๋งํ๊ธฐ ๋๋ฌธ์, ์ฝ์์ ์ํด undefined
์(๊ทธ๋ ์ง ์์ ์)๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์์ต๋๋ค ๋ฐ์์ฉ ๊ฒ์ ๋ณด์ฌ Loading...
ํ
์คํธ๋ฅผ.
์์ : ์์ ํ์ต๋๋ค.
@sedubois @polytypic ๋ํ Promise๊ฐ ์ ํ ์ฒ๋ฆฌ๋์ง ์๊ธฐ ๋๋ฌธ์ ํจ์ ๋ด์์ ๋ฐ์ํ ๋ชจ๋ ์ค๋ฅ๊ฐ ์กฐ์ฉํ ๋ฌด์๋ฉ๋๋ค.
@polytypic @dantman "์ฝ์์ด ์ ํ ์ฒ๋ฆฌ๋์ง ์์"์ด ๋ฌด์์ ์๋ฏธํ๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. await
์ฐ์ฐ์๊ฐ ๊ธฐ๋ค๋ฆฌ๊ณ ์์ต๋๋ค. ์ค๋ฅ๋ฅผ ์ก์์ผ ํฉ๋๋ค. ์์ ๋ฅผ ์
๋ฐ์ดํธ ํ์ต๋๋ค(Apollo๊ฐ ์ํํ๋ ๊ฒ๊ณผ ์ ์ฌํ ๋ก๋ฉ/์ค๋ฅ ์๋ช
์ฌ์ฉ).
try {
this.setState({ message: await getMessage() });
} catch(error) {
this.setState({ error });
}
๊ทธ๋ฆฌ๊ณ ๋ ๋๋ง:
{error ? error : loading ? 'Loading...' : message}
@sedubois async
ํจ์๊ฐ ์์์ ์ผ๋ก ์ฝ์์ ๋ฐํํ ๋ ํจ์์ ๋ชจ๋ throw
๋ ์คํ์ ๋์ง๋ ๋์ ์์์ ์ผ๋ก ํด๋น ์ฝ์์ ๊ฑฐ๋ถํ๋ ๊ฒ์ผ๋ก ๋ฐ๋๋๋ค. ์ด๊ฒ์ componentWillMount
๊ฐ ์ด์ ํธ์ถ์์๊ฒ ์ฝ์์ ๋ฐํํ๊ณ ์์์ ์๋ฏธํฉ๋๋ค.
React๋ ๋ฐํ ๊ฐ์ผ๋ก ์๋ฌด ์์ ๋ ํ์ง ์์ผ๋ฏ๋ก ํจ์๋ ์ด์ ๋๊ตฐ๊ฐ๊ฐ ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌด์ธ๊ฐ๋ฅผ ํ ๊ฒ์ด๋ผ๊ณ ๊ธฐ๋ํ๋ Promise๋ฅผ ๋ฐํํ์ง๋ง ๋์ ๊ทธ๋ฅ ๋ฒ๋ ค์ง๋ ๊ฒ์ ๋๋ค.
์ฒ๋ฆฌ๋์ง ์๊ธฐ ๋๋ฌธ์ ํด๋น ์ฝ์์ ๊ฑฐ๋ถ๋ React์ ์ด๋ค ์ฝ๋์์๋ ํฌ์ฐฉ๋์ง ์์ผ๋ฉฐ ์ฒ๋ฆฌ๋์ง ์์ ์ค๋ฅ๋ ์ฝ์์ ํ์๋์ง ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ try..catch๋ฅผ ํด๋ ์๋ฒฝํ๊ฒ ๋ณดํธ๋์ง๋ ์์ต๋๋ค. setState
์์ catch์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฑฐ๋ catch์์ ์คํ๊ฐ ๋ฐ์ํ๋ฉด ํด๋น ์ค๋ฅ๊ฐ ์๋์ผ๋ก ์ฌ๋ผ์ง๊ณ ๋ฌด์ธ๊ฐ๊ฐ ๊นจ์ก๋ค๋ ๊ฒ์ ์ธ์ํ์ง ๋ชปํ ๊ฒ์
๋๋ค.
@sedubois ์ฌ์ค, ๋น๋๊ธฐ ๋ฉ์๋๋ ํญ์ JavaScript(๋ฏธ๋์ JavaScript)์์ ์ฝ์์ ๋ฐํํ๋ ๊ฒ ๊ฐ์ต๋๋ค. C#์์ async-await ๋ฌธ์ ์ ๋ํด ์๊ฐํ๋ ๊ฒ์ด ํผ๋์ค๋ฌ์ ์ต๋๋ค. _์์ ์ฃ์กํฉ๋๋ค!_
๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ์คํฌ๋ฆฐ์ท์ React๊ฐ ์ฝ์์ด ํด๊ฒฐ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์๋๋ค๋ ๊ฒ์ ๋ถ๋ช
ํ ๋ณด์ฌ์ค๋๋ค. componentWillMount
ํธ์ถํ ์งํ render
๋ฅผ ํธ์ถํ๊ณ Loading...
ํ
์คํธ๋ฅผ ๋ ๋๋งํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ setState
ํธ์ถ ํ render
๋ค์ ํธ์ถํฉ๋๋ค. React๊ฐ ์ฝ์์ด ํด๊ฒฐ๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๋ฉด Loading...
ํ
์คํธ๋ฅผ ์ ํ ๋ ๋๋งํ์ง ์์ ๊ฒ์
๋๋ค. ๋์ , ์ฝ์์ด ํด๊ฒฐ๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ render
๋ง ํธ์ถํฉ๋๋ค. ์ด๋ ์๋ฒ ์ธก ๋ ๋๋ง ์ค์ ๋น๋๊ธฐ IO๋ฅผ ์ํํ ์ ์๋ ์ด ๋ฌธ์ ์ ๋ชจ๋ ์ข
๋ฅ์ ๋์์
๋๋ค.
@dantman @polytypic ๊ฐ์ฌํฉ๋๋ค ๐ ์, ์๋ต์ ๊ธฐ๋ค๋ฆฌ๊ณ ์ค๋ฅ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ์ฒ๋ฆฌํ๋ ค๋ฉด React ๋ด๋ถ์์ ๋ณ๊ฒฝ์ด ํ์ํฉ๋๋ค. ์ฝ๋์ ์ฌ๊ธฐ ์ ๊ธฐ์ await
์ถ๊ฐํ๋ฉด ๋ฉ๋๋ค. ๐
๊ฐ์ธ์ ์ผ๋ก ์ ๋ ์น ์์ ์๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ํ๋ฅผ ์ ์ฅํ๊ณ ๋ณ๊ฒฝ ์ ์ํ์ ๋ด๋ณด๋ด๊ณ ์์ต๋๋ค(๋ฐ์ดํฐ ์ ์ฅ์๋ฅผ ์์ ํ ๋ถ๋ฆฌํ๊ณ React ๊ตฌ์ฑ ์์์์ ๊ฐ์ ธ์ค๊ณ React๋ฅผ ๋ ๋๋ฌ์ฒ๋ผ ์ทจ๊ธํ์ฌ ๋จ๋ฐฉํฅ ํ๋ฆ ์์น์ ์ ์งํจ). ๋ ๋๋งํ ์์ ์๊ตฌ ์ฌํญ(์: ํน์ ์์ฑ์ด true์ธ ๊ฒฝ์ฐ)์ด ํฌํจ๋ ๋ฉ์์ง์ ๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ์ฒซ ๋ฒ์งธ ๋ฉ์์ง๊ฐ ์ค๊ฐ "๋ก๋ ์ค" ์ํ์ธ ๊ฒฝ์ฐ์๋ ๋น๋๊ธฐ ๊ตฌ์ฑ ์์ ๋ฉ์๋๊ฐ ํ์ ์์ด ์ ์ ์๋ฒ ์ธก ๋ ๋๋ง์ ์ฌ์ฉ๋์ง ์์ต๋๋ค.
@sedubois ๋ค๋ฅธ ๋ฉ์๋ ์คํ์ด ์์ด์ผ ํฉ๋๋ค. ๋๋ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ. React์ ํ์ฌ ๋ ๋๋ง ๋ฐฉ๋ฒ์ ๋๊ธฐํ์ด๋ฏ๋ก ์ฝ์์ ๋ฐํํ๋ ๋ค๋ฅธ ์๋ฒ ๋ ๋๋ง ๋ฐฉ๋ฒ์ด ํ์ํฉ๋๋ค.
@dantman ๋๋ ์ด ๋ฌผ์ด ๋์๊ฒ ๋๋ฌด ๊น๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์ ์ด๋ค ์๊ฒฌ๋ ์ ์ํ๊ณ ์ถ์ง ์์ต๋๋ค(๋ด ์ด๊ธฐ ๋ชฉํ๋ Vjeux์ async componentWillMount ํดํน์ ์ง์ ํ๋ ๊ฒ๋ฟ์ด์์ต๋๋ค...), ํ์ง๋ง ํ , React๋ ๋ค์ ์ ํ์ ๋ณผ ์ ์์ต๋๋ค. ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋์ ์ํด ๋ฐํ๋ ๊ฐ์ฒด์ด๊ณ ์ฝ์์ธ ๊ฒฝ์ฐ ๋น๋๊ธฐ ์ฒ๋ฆฌํ๊ณ ๊ทธ๋ ์ง ์์ผ๋ฉด ๋๊ธฐํ ์ฒ๋ฆฌ(ํ์ฌ, ์ฆ ์ด์ ๋ฒ์ ๊ณผ ํธํ๋๋ ๋ฐฉ์์ผ๋ก)?
@fkrauthan์ด ์ ์ํ ๊ฒ์ ์ข์ํฉ๋๋ค. ํ๋ผ๋ฏธ์ค ๋๋ undefined
๋ฐ ์ถ๊ฐ ๋น๋๊ธฐ renderToStringAsync
ํจ์๋ฅผ ๋ฐํํ ์ ์๋ ์๋ช
์ฃผ๊ธฐ ๋ฉ์๋ load
. ๊ทธ๋ฌ๋ load
๋ ํญ์ ํด๋ผ์ด์ธํธ์ ์๋ฒ์์ ํธ์ถ๋์ด์ผ ํฉ๋๋ค. render
๋๋ renderToString
ํ๋ ๊ฒฝ์ฐ ๋ฐํ๋ ์ฝ์์ ์ค๋๋ ์ ๋์๊ณผ ์ผ์นํ๋๋ก ๋ฌด์๋ฉ๋๋ค. renderToStringAsync
ํ๊ณ load
๊ฐ ์ฝ์์ ๋ฐํํ๋ฉด ๋ ๋๋ง ์ ์ ์ฝ์์ ํด๊ฒฐํด์ผ ํฉ๋๋ค.
Next.js ์ฒ๋ผ ์์ฑ์๋ณด๋ค ๋จผ์ ํธ์ถ๋๋ React async getInitialProps
์๋ช
์ฃผ๊ธฐ ํจ์๋ฅผ ์ถ๊ฐํ์ง ์์ผ ์๊ฒ ์ต๋๊น? ์ด๋ฌํ ๋ฉ์๋๊ฐ ์์ผ๋ฉด ์์ฑ์๋ฅผ ์ง์ ํธ์ถํฉ๋๋ค.
const props = await (Component.getInitialProps ? Component.getInitialProps(ctx) : {});
...
const app = createElement(App, {
Component,
props,
...
});
Next.js์ getInitialProps
๊ฐ React ๊ตฌ์ฑ ์์ ์๋ช
์ฃผ๊ธฐ์ ์ฐ๊ฒฐ๋์ง ์์ ์ต์์ ๊ตฌ์ฑ ์์์์๋ง ํธ์ถํ ์ ์๋ค๋ ์ ์ ์ ์ธํ๋ฉด Next.js๊ฐ ์์
์ ์ํํ๋ ๊ฒ์ฒ๋ผ ๋ณด์
๋๋ค. ๊ทธ๋์ ์์ด๋์ด๊ฐ ์๊ณ ๊ทธ๋ฅ ํจ๊ป ๊ฒฐํฉํ ์ ์์ต๋๊น?
@sedubois getInitialProps๊ฐ ์ฌ๋ฐ๋ฅธ ์ฅ์๊ฐ ์๋๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ฐ์ ES6์ ์ฌ์ฉํ๋ ์ฌ๋๋ค์ ๊ทธ ๋ฐฉ๋ฒ์ด ์๊ฑฐ๋ ์ฌ์ฉํ์ง ์์ต๋๋ค. ๋ ๋ฒ์งธ๋ก initalProps + props์ ์ ๋ฌ๋ initalProps ๋ณํฉ ์์ ์์
ํ๋ ค๋ initalProps(๊ธฐ๋ณธ๊ฐ์ผ ๋ฟ)์์ ์์
ํ๊ณ ์ถ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ componentWillMount
์ ์ ์ ๋ฌ๋๋ ์๋ก์ด ์๋ช
์ฃผ๊ธฐ ์ด๋ฒคํธ๋ฅผ ์ ์ํฉ๋๋ค.
@Lenne231 ์์ด๋์ด๋ ์ฌ๋๋ค์ด ์ด๋ฏธ ํด๊ฒฐ๋ ์ฝ์์ ๋ํ ๋ค๋ฅธ ์๋ช ์ฃผ๊ธฐ ์ด๋ฒคํธ๋ฅผ ๋ฆด๋ ์ดํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ช ๊ฐ์ง ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด์ ๋์ผํ ์๋ช ์ฃผ๊ธฐ ์ด๋ฒคํธ์ ๋ํด ๋ ๊ฐ์ง ๋ค๋ฅธ ๋์์ด ์์ผ๋ฏ๋ก ์ฝ๊ฐ ๊น๋ค๋กญ์ต๋๋ค.
๋ฐ๋ผ์ ์๋ฒ์ ํด๋ผ์ด์ธํธ์๋ ์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ ํ ํธ์ถํ์ง ์๋ ๋๊ธฐํ ๋ ๋๋ง ๋ฉ์๋๊ฐ ํ๋ ์์ด์ผ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ํด๋น ์๋ช ์ฃผ๊ธฐ๋ฅผ ํธ์ถํ๊ณ ๊ณ์ ์งํํ๊ธฐ ์ ์ ์ฝ์์ด ํด๊ฒฐ๋ ๋๊น์ง ํญ์ ๊ธฐ๋ค๋ฆฌ๋ ๋น๋๊ธฐ ๋ฒ์ ์ ๋๋ค. ์ ์๊ฐ์๋ ํด๋ผ์ด์ธํธ ๋ ๋์๋ ํด๋น ์๋ช ์ฃผ๊ธฐ๊ฐ ํ์ํ์ง ์๋๋ฉด ์๋ฒ ๋ ๋์๋ง ํ์ํ์ง ๊ฒฐ์ ํ ์ ์์ผ๋ฏ๋ก ์ต๊ณ ์ ์ ์ฐ์ฑ์ ์ ๊ณตํ ๊ฒ์ ๋๋ค.
ES6์ ์ฌ์ฉํ๋ ์ฌ๋๋ค์ ๊ทธ ๋ฐฉ๋ฒ์ด ์๊ฑฐ๋ ์ฌ์ฉํ์ง ์์ต๋๋ค.
@fkrauthan ์๋ง๋ getInitialState
ํ์๊ฒ ์ต๋๊น? ์ฌ๊ธฐ์ ์ ๋ ์๋ก์ด getInitialProps
(Next.js์์ ์ฌ์ฉ๋ ์ด๋ฆ)์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์์ต๋๋ค.
๋ ๋ฒ์งธ ์์ ์ ์, constructor
์ด์ ๋ณด๋ค componentWillMount
์ด์ ์ ์ ์๋ช
์ฃผ๊ธฐ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋์ ์ ์์ต๋๋ค. ์ด์ ์ ์ธ๊ธํ ๋๋ก React ์๋ช
์ฃผ๊ธฐ๋ฅผ ์กฐ์ ํ ์ ์๋ ์ฌ์น๊ฐ ์๊ธฐ ๋๋ฌธ์ Next์์๋ ๊ทธ๋ ์ง ์์ ๊ฒ ๊ฐ์ต๋๋ค. ๋ฐ๋ผ์ React ๋ด์์ ์ด๋ฌํ ์์ด๋์ด๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ด ์ข์ต๋๋ค.
@sedubois ๊ทธ๊ฒ๋ . ์๋ฅผ ๋ค์ด es7 ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ณ ํด๋์ค ๋ณธ๋ฌธ์ static props = {};
์ ์ํฉ๋๋ค. ๊ทธ๋ ๊ฒ ํ๋ฉด ์ ์๊ฐ์๋ ์ฝ๋๋ฅผ ๋ ์ฝ๊ธฐ ์ฝ๊ฒ ๋ง๋ค ์ ์์ผ๋ฉฐ es7์ด ๊ณต์์ ์ผ๋ก ์ถ์๋์๋ง์ ์ ์ ๋ ๋ง์ ์ฌ๋๋ค์ด ์ด ์ฝ๋๋ก ์ ํํ ๊ฒ์ด๋ผ๊ณ ํ์ ํฉ๋๋ค.
์ฐธ๊ณ : ํด๋์ค ์์ฑ์ "ES7" ๊ธฐ๋ฅ์ด ์๋๋๋ค. ES7์ด ์ด๋ฏธ ์์ฑ๋์์ผ๋ฉฐ ์ง์ ์ฐ์ฐ์๋ง ์๋ก ์ถ๊ฐ๋ ์ธ์ด ๊ธฐ๋ฅ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋น์ ์ด ๋งํ๋ ๊ฒ์ 2๋จ๊ณ ํด๋์ค ์์ฑ ์ ์ ์ ๋๋ค. ์์ง ์ธ์ด์ ์ผ๋ถ๊ฐ ์๋๋ฉฐ ๋ณ๊ฒฝ๋๊ฑฐ๋ ์ญ์ ๋ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ ๋ฐ์์์ ๋น๋๊ธฐ ํจ์๊ฐ ํ์ํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋์ ์์ฒญ ์ renderToString์ ์ฌ์ฉํ๋ ๊ฐ์ ๋ ๋๋ฌ๊ฐ ์์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค. ๋ฐ๋ผ์ ์์ ์ ์ค์ ํ ์ ์์ผ๋ฉฐ ๊ฐ์ ํธ๋ฆฌ๋ ๋ฌธ์์ด๋ก ๋ ๋๋งํ๊ธฐ ์ ์ ๊ทธ์ ๋ฐ๋ผ ์ ๋ฐ์ดํธ๋ฉ๋๋ค. ์ด๊ฒ์ ๋ฐ์์์ ์ข์ SSR์ ๋ฌ์ฑํ๋ ๋ฐ ์ด์์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ๊ณผ ์์น๋ ๊ฐ๋ฐ์์๊ฒ ๋งก๊น๋๋ค.
์ด์ ์ ์ธ๊ธํ์ง๋ง ์ข์ API๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค(์ด์ ์ ์ ์ํ ๋ด์ฉ์ ์ฝ๊ฐ ์ ๋ฐ์ดํธํจ).
const virtualTree = ReactDOM.renderVirtual(rootEle);
// get the bundled query from redux store for example
const bundle = store.getState().bundle;
// Fetch the data according to the bundle
const data = await fetchDataSomehow(bundle);
// hydrate store (this will set updates on the virtual tree)
store.dispatch({type: 'hydrate', data});
// final result
const domString = virtualTree.renderToString();
์ด๋ ๊ฒ ํ๋ฉด Apollo์ ๊ฐ์ ์ผ๋ถ GraphQL ํด๋ผ์ด์ธํธ๊ฐ ์ด์ค renderToString์ ๋ง๋ค๋๋ก ๊ฐ์ ํ๋ ๋ฌธ์ ๋ฅผ ํผํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ ์ข ์์ฑ์ ๊ฐ์ฅ ๋จผ์ ๊ฐ์ ธ์ค๊ณ ๋ ๋ฒ์งธ๋ ๋ฐ์ดํฐ๊ฐ ์ฑ์์ง ์ํ๋ก ๋ ๋๋งํฉ๋๋ค. renderToString์ด ์๋นํ ๋น์ธ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ด ์ฒ๋ฆฌ ๋ญ๋น๋ผ๊ณ ์๊ฐํฉ๋๋ค.
@bruno12mota ๋๋ ๋น์ ์ ์์ ์ ์์ง๋ง ๋ค์ ๊ทธ๊ฒ์ ์๋ฎฌ๋ ์ด์ ํ๋ ค๊ณ ์๋ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์(๋น์ ์ ์๋ฃจ์ ์๋ ์ฌ์ ํ ์์ฒ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ ๊ฒ์ ๋๋ค)์ ๋์๊ฒ ๊ทธ๊ฒ์ด ์๋ง๋ ๋น์ ์ด ํด์ผ ํ๋ ๊ฒ์ด ์๋๋ผ ํต์ฌ ๊ธฐ๋ฅ์ด ๋์ด์ผ ํ๋ค๋ ์ ํธ์ ๋๋ค. ์์ ๋น๋ํฉ๋๋ค. ์๋ฃจ์ ์ ์ถ๋ ฅ์ ์ป๊ธฐ ์ํด ์ฌ์ ํ ๋ ๋ง์ ๋ ๋๋ง ํธ์ถ(๊ฐ์์ด์ง๋ง ์ฌ์ ํ ๋ ๋๋ง ํธ์ถ)์ด ํ์ํฉ๋๋ค.
@fkrauthan ๋ค, ํ์ง๋ง ๊ฐ์ ๋ ๋๋ ๋ฌธ์์ด์ 2๊ฐ์ ๋ ๋๋ฅผ ๋ง๋๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋ ์ฑ๋ฅ์ด ์ข์ต๋๋ค. ์ ์๊ฐ์๋ ์ฌ๊ธฐ์์ ์ฃผ์ ๋ฌธ์ ์
๋๋ค(SSR์ ์ฑ๋ฅ). React์ ์ฝํ ๋ถ๋ถ์
๋๋ค. ๋ฐ์์ renderToString
๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํ ๋ช ๊ฐ์ง ์คํ์ด ์์์ง๋ง ๋ฐ์ ํ์์ ์ด ๋ฌธ์ ์ ๋ํด ์ค์ง์ ์ธ ์ง์ ์ด ์์์ต๋๋ค(์ฌ๊ธฐ์ ๋นํํ์ง ์๊ณ ๋๋ผ์ด ์ผ์ ํ๊ณ ์์ต๋๋ค).
๋๋ @bruno12mota ์ ๋์ํฉ๋๋ค. ์ด ๋ฌธ์ ์ ๋ํด์๋ ์ ์ ๋์ ์๊ณ ํ ์ ์ด ์์ต๋๋ค. ์ด๊ฒ์ด ๊ฐ์ฅ ๊ฐ๋จํ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ๋ ๋๋ง์ด "ํ๋ฌ์"๋์ด์ผ ํ๋ ์๊ธฐ๋ฅผ ๊ฒฐ์ ํ ์ ์๋ ์์ ๋ ๊ฐ๋ฐ์์๊ฒ ์์ต๋๋ค.
๊ทธ๊ฒ์ ๋ชจ๋ ๊ฒ์ ํจ์ฌ ๋ ๋ณต์กํ๊ฒ ๋ง๋ญ๋๋ค.
1.) ์ฝ๋ ๊ด์ ์์ (์ฝ๋๋ฅผ ์ดํด๋ณด๊ณ ๋ ๋๋ง ๋น๋๊ธฐ๋ฅผ ๋ง๋๋ ๊ฒ์ด VDom์ ์ฌ์ฉํ๋ ๋ ๋๋ฌ๋ฅผ ๋ง๋ ๋ค์ ํ ์ง์ ์์ ๋คํํ ์ ์๋ ๋ ๋๋ฌ๋ฅผ ๋ง๋๋ ๊ฒ๋ณด๋ค ํจ์ฌ ์ฌ์์ผ ํจ)
2.) ์ด์ ๋ง์ดํธ ํด์ ์ด๋ฒคํธ๋ ๋ค์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ ์ฌ์ฉ์ ์ ์ ์ฝ๋๋ฅผ ํ์ ์ด์์ผ๋ก ๋ณต์กํ๊ฒ ๋ง๋ญ๋๋ค. ์๋ฅผ ๋ค์ด ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํด์ผ ํ๋ ์ ๊ตฌ์ฑ ์์๊ฐ ๋ ๋๋ง๋ ์ ์์ต๋๋ค. ์ด์ ๊ฐ์๊ธฐ lib๋ ์ด๋ ์์น์์ ์ด๋ฏธ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ ๊ตฌ์ฑ ์์์ ์ด๋ค ๊ตฌ์ฑ ์์์ ์ ๋ฐ์ดํฐ ๋ก๋ ๋ฐ ํญ๋ชฉ์ด ํฌํจ๋์ด ์๋์ง ํ์
ํด์ผ ํฉ๋๋ค.
@bruno12mota ์ ํจ๊ป ํฉ๋๋ค. VDom์ ํ๋ฆผ์์ด ๋ "์ ์์ค" ์๋ฃจ์ ์ด์ง๋ง React ๊ฐ๋ฐ์๊ฐ ๊ตฌํํ๊ธฐ๊ฐ ๋ ์ฌ์ฐ๋ฉฐ ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ ๋ฌธ์ ๊ฐ ์์ผ๋ฉฐ ์ปค๋ฎค๋ํฐ์์ ๋ค๋ฅธ ๋ ๋์ ์์ค์ ์๋ฃจ์ ์ ์คํํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, ํ๋์ ์์ ์์ค ์๋ฃจ์
์ ๋น๋๊ธฐ componentWillMount
๋ฉ์๋๋ฅผ ๋ํํ๊ณ ๋ณด๋ฅ ์ค์ธ ๋ชจ๋ ์ฝ์์ ๊ธฐ๋ค๋ฆฌ๊ณ ๋ชจ๋ ๊ฒ์ด ํด๊ฒฐ๋๋ฉด VDom.renderToString()
ํ๋ "์์ ์์ค ๊ตฌ์ฑ ์์"๊ฐ ๋ ์ ์์ต๋๋ค. ๋ถํํ๋ VDom์ด ์๊ธฐ ๋๋ฌธ์ ์ง๊ธ ๋น์ฅ์ ๋ง์ด ๊ฐ์ ธ์ค๊ธฐ๋ ํ์ง๋ง ๋ด ์ฑ์์ ์ด๋ฌํ ์ข
๋ฅ์ SSR ์ ๋ต์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
ํ์ฌ ๊ฐ์ง๊ณ ์๋ ๊ธฐ๋ฅ์ ๋ณ๊ฒฝํ์ง ์๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ฆ, getInitialState, componentWillMount ๋๋ renderToString์ด ๋ค๋ฅด๊ฒ ์๋ํ์ง ์๋๋ก ํฉ๋๋ค.
๋์ ์ฌ๊ธฐ์ ๋ ผ์๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ํด๋ผ์ด์ธํธ์์๋ง ํธ์ถ๋๋ ํจ์๊ฐ ์๋ ๊ฒ์ฒ๋ผ ์๋ฒ์์๋ง ํธ์ถ๋๋ ํจ์๊ฐ ์์ ์ ์์ต๋๋ค.
react-dom/server์ "renderToStringAsync" ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ผ๋ฐ renderToString๊ณผ์ ์ฐจ์ด์ ์ Promise๋ฅผ ๋ฐํํ๋ค๋ ๊ฒ์ ๋๋ค.
๊ตฌํ ์ธก๋ฉด์์ ์ ์ผํ ์ฐจ์ด์ ์ ๋น๋๊ธฐ ๋ฒ์ ์ด Component ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋๋ง๋ค render()๋ฅผ ํธ์ถํ๊ธฐ ์ ์ ๋จผ์ "initialize()"๋ฅผ ํธ์ถํ๊ณ ๋๊ธฐํ๋ค๋ ๊ฒ์ ๋๋ค. ๊ตฌ์ฑ ์์์ "์ด๊ธฐํ" ๋ฉ์๋๊ฐ ์์ผ๋ฉด ์ฆ์ render()๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ๋ค์ ์์ ์ฑ ๊ตฌ์กฐ๊ฐ ์๋ ๊ฒฝ์ฐ:
ComponentB
ComponentC
ComponentD
ComponentE
ํ๋ก์ธ์ค๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
1) instanciate componentA
2) await componentA.initialize();
3) componentA.render()
4) do in parallel(
instanciate componentB, await componentB.initialize(), componentB.render()
instanciate componentC, await componentC.initialize(), componentC.render(), do in parallel(
instanciate componentD, await componentD.initialize(), componentD.render()
instanciate componentE, await componentE.initialize(), componentE.render()
)
)
5) render to string
๋ฐ๋ผ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ก์ด ์ ํ์ ๊ธฐ๋ฅ์ธ "initialize"๋ฅผ ์ฌ์ฉํ๋ "renderToStringAsync"๋ผ๋ ์ ๊ธฐ๋ฅ๋ง ์์ผ๋ฉด ๋ฉ๋๋ค. ๊ทธ๋ ๊ฒ ์ด๋ ต์ง ์์ ๊ฒ์ ๋๋ค.
@VanCoding ์ ๋ด๊ฐ ์ ์ ๋์ ์๊ฐํ๋ ๊ฒ๊ณผ ๊ฐ์ ์์ด๋์ด๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ํด๋ผ์ด์ธํธ์ componentDidMount์์ initialize๊ฐ ์๋์ผ๋ก ํธ์ถ๋ ์๋ ์๋์ง ๊ถ๊ธํฉ๋๋ค.
๋ฐ๋ผ์ ์๋ฒ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
initialize()
render()
ํด๋ผ์ด์ธํธ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
render() // without data (unless available synchronously)
componentDidMount()
initialize()
render() // with data
react-router v4๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ ์๋ฒ ๋ ๋๋ง์ ๊ตฌํํ๊ณ GraphQL์ ์ฌ์ฉํ์ฌ react-apollo๋ฅผ ๊ตฌํํ์ต๋๋ค.
๊ทธ๊ฒ์ server-side-rendering-code-splitting-and-hot-reloading-with-react-router ์์ ์๊ฐ์ ๋ฐ์์ต๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฒ ๋ ๋๋ง์ ๋๊ธฐํ๋ ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํ๊ณ ํด๋ผ์ด์ธํธ ๋ ๋๋ง์ ๋น๋๊ธฐํ๋ ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ์นํฉ ๋น๋๊ธฐ ๋ก๋ฉ ๋ฐ ์คํ ๋ชจ๋ ์๋ฐ ์คํฌ๋ฆฝํธ.
๊ทธ๊ฑด ๊ทธ๋ ๊ณ ์๋ฒ ๋ ๋๋ง์ Nashorn ์คํฌ๋ฆฝํธ ์์ง(JVM)์ผ๋ก ๊ตฌํ๋ฉ๋๋ค.
ํด๋ผ์ด์ธํธ ๋ ๋๋ง ์ฝ๋
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/main.js#L63 -L82
์๋ฒ ๋ ๋๋ง ์ฝ๋
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/main.js#L128 -L155
๊ฒฝ๋ก์์ ๋๊ธฐํ๋ ๊ตฌ์ฑ ์์์ ๋น๋๊ธฐํ๋ ๊ตฌ์ฑ ์์๋ฅผ ๊ตฌ๋ณํ๋ ์ค์ํ ์์น๊ฐ ํ๋ ์์ต๋๋ค.
Route์ ๋๊ธฐํ๋ ๊ตฌ์ฑ ์์
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/routes/Counter/Route.js#L10
RouteAsync์ ๋๊ธฐํ๋ ๊ตฌ์ฑ ์์
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/src/routes/Counter/RouteAsync.js#L7 -L23
์ฐธ๊ณ : ํ์ผ ์ด๋ฆ์ Route.js ๋๋ RouteAsync.js์ฌ์ผ ํฉ๋๋ค. ์ฝ๋๋ ํญ์ RouteAsync.js๋ฅผ ๊ฐ์ ธ์์ผ ํฉ๋๋ค. Webpack์ ์๋ฒ ๋ ๋๋ง์ฉ์ผ๋ก ๋น๋๋ ๊ฒฝ์ฐ ์ด๋ฅผ Route.js๋ก ๋์ฒดํฉ๋๋ค.
https://github.com/shendepu/react-ssr-starter-kit/blob/apollo/build/webpack.config.js#L72 -L80
๋ฐ๋ผ์ dist
๋ฐ dist_ssr
๋น๋์ ๋ ๊ฐ์ง ๋ฒ์ ์ด ์์ต๋๋ค. dist
๋ ํด๋ผ์ด์ธํธ์ฉ์ด๊ณ dist_ssr
๋ ๊ณต๊ธ์
์ฒด์ ์ฑ์ ๋ ์ฒญํฌ๋ง ์๋ ์๋ฒ์ฉ์
๋๋ค. . ์์ ์ํ๋ index.html์ <script>
์ __INITIAL_STATE__
๋ก ๋ด๋ณด๋ด์ง๊ณ ํฌํจ๋ฉ๋๋ค. ๋ ๊ฐ์ง ๋ฒ์ ์ ๋น๋๊ฐ ์๋ ์ด์ ๋ ReactDomServer.renderToString()
๊ฐ ์์ง ๋น๋๊ธฐ ๊ตฌ์ฑ ์์๋ฅผ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ ๊ฐ์ง ๋ฒ์ ๋น๋ ์ ๊ทผ ๋ฐฉ์์ ์ ์ผํ ๋ฌธ์ ๋ ๊ฐ๋ฐ ๋ชจ๋์ ๊ฒฝ๊ณ ๊ฐ ์๋ค๋ ๊ฒ์
๋๋ค.
React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
๊ทธ๋ฌ๋ ํด๋ผ์ด์ธํธ ๋ฒ์ ๊ณผ ์๋ฒ ๋ฒ์ ์ ์ฐจ์ด์ ์ Route.js์ RouteAsync.js๋ฟ์ด๋ฏ๋ก ๊ฒฝ๊ณ ๋ฅผ ๋ฌด์ํ ์ ์์ผ๋ฏ๋ก ํ๋ก๋์ ๋ชจ๋์์๋ ๊ฒฝ๊ณ ๊ฐ ํ์๋์ง ์์ต๋๋ค.
์๋ฒ ์ธก์์ ๊ตฌ์ฑ ์์ ๋ ๋๋ง ์ ์ ๋น๋๊ธฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ๊ฒฝ์ฐ:
const { matchedRoutes, params } = matchRoutesToLocation(rootRoute.routes,
location, [], {}, rootRoute.pattern)
matchedRoutes.filter(route => route.component.loadData).map(route =>
route.component.loadData(store, params))
loadData
๋ฅผ ์กฐ์ฌํ๊ณ ์คํํฉ๋๋ค. MatchedRoutes๋ ๋ถ๋ชจ๊ฐ 0
์ธ๋ฑ์ค์ ์๋ ์ผ์นํ๋ ๊ฒฝ๋ก์ ๋ฐฐ์ด์
๋๋ค. loadData
๋ ์์ฐจ์ ์ผ๋ก ๋๋ ๋ณ๋ ฌ๋ก ์คํํ ์ ์์ต๋๋ค.
getDataFromTree
์์ react-apollo/server
๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ GraphQL ์ฟผ๋ฆฌ๋ฅผ ์คํํฉ๋๋ค.BTW: Nashorn Script Engine์ ์ฌ์ฉํ๋ฉด ํ ๊ฐ์ง ์ฑ๋ฅ ์ต์ ํ ๊ธฐํ๊ฐ ์์ต๋๋ค. ๊ณต๊ธ์ ์ฒด์๋ ํ ๋ฒ ์คํ๋๊ณ ์ฌ์ฌ์ฉ๋๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฝ๋์ ํด๋ฆฌํ์ด ํฌํจ๋์ด ์์ผ๋ฏ๋ก ์ดํ ์์ฒญ์ ๋ํด์๋ ์ฑ ์ฒญํฌ๋ง ์คํ๋ฉ๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ฒค๋ ์ฒญํฌ๋ก ์ด๋๋๊ธฐ ๋๋ฌธ์ ์ฑ์ src์ ์์ ์๋ฐ ์คํฌ๋ฆฝํธ ์ฝ๋๋ง ํฌํจํ๋ฏ๋ก ๋งค๋ฒ ๋ฒค๋ ์ฒญํฌ๋ฅผ ํ๊ฐํ๋ ๊ฒ์ ๋นํด ์ฑ๋ฅ์ด ํฅ์๋ฉ๋๋ค. (๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ ํ ๋ฒ ์ปดํ์ผ๋๊ณ ์บ์๋์ด ๋ชจ๋ ์์ฒญ์ โโ๋ํด ์คํ๋ฉ๋๋ค.)
์ฑ ์ฒญํฌ์๋ src ์ฝ๋๋ง ํฌํจ๋์ด ์๋ค๊ณ ๊ฑฐ์ง๋ง์ ํ์ต๋๋ค. ๋ํ babel-runtime
๋ฐ core-js/library
์ฐธ์กฐํ๋ ๋ณต์ ๋ babel-runtime
ํฉ๋๋ค. babel-runtime
๋ index.js ๋๋ ๊ธฐ๋ณธ ํญ๋ชฉ์ด ์์ผ๋ฏ๋ก webpack์ด ๋ชจ๋๋ก ์ธ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ณต๊ธ์
์ฒด ์ฒญํฌ๋ก ์ด๋ํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฝ๋ ํฌ๊ธฐ๋ ์์ต๋๋ค.
@VanCoding ์ ์๋ฅผ ๋ ์์ธํ ์ค๋ช ํ๊ฒ ์ต๋๋ค. https://github.com/facebook/react/issues/1739#issuecomment -261577586
initialize๋ ์ข์ ์ด๋ฆ์ด ์๋ ์ ์์ต๋๋ค. ์ด๋ฆ์ ์๋ฒ์์๋ง ์ฌ์ฉ๋๊ฑฐ๋ ์ด ํจ์๊ฐ ๋ฐํ๋ ๋๊น์ง ๋ ๋๋ง์ด ์ง์ฐ๋๋ ํ๊ฒฝ(์ผ๋ช
ํด๋ผ์ด์ธํธ์์๋ ์ฌ์ฉํ์ง ์์)์์๋ง ์ฌ์ฉํ๋๋ก ์๋๋์์์ ๋ถ๋ช
ํ ํด์ผ ํฉ๋๋ค. ์์ด๋์ด: getStaticProps
, getServerProps
, getInitialProps
, getAsyncProps
...
๋ํ ์ด๋ฌํ renderToStringAsync ๋ฉ์๋๋ฅผ ๊ฐ๋ฐํ๋ ๋ฐ ๊ธฐ์ ์ ์ธ ๋๋ ๋ค๋ฅธ ์ฅ์ ๋ฌผ์ด ์๋์ง ์ฌ๋ถ๋ฅผ ํต์ฌ ํ์์ ๋ฃ๋ ๊ฒ์ด ์ข์ต๋๋ค.
@nmaro ๊ธ์์, ํจ์๋ ์๋ฌด ๊ฒ๋ ๋ฐํํ์ง ์์์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋์ "get"์ผ๋ก ์์ํ์ง ์๋ ์ด๋ฆ์ ์ ํธํ์ง๋ง ์ด๊ฒ ์ธ์๋ ์ฌ์ ํ ์ด๊ฒ์ด ์ต์ ์ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ๊ฒฐ๊ตญ ์ด๋ป๊ฒ ๋ถ๋ฆฌ๋์ง ์๊ดํ์ง ์์ต๋๋ค.
๊ฒ๋ค๊ฐ ์ฝ 40์ค์ ์ฝ๋๋ก ์ด์ ๋ํ ๊ฐ๋ ์ฆ๋ช ์ ์ํ
๋ฐ๋ผ์ ๋ฐ์ ํ์ด ์ฌ์ ํ ์ด๊ฒ์ด ๋ฐ์ํ๋ ๊ฒ์ ์ํ์ง ์๋๋ค๋ฉด ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ํํ๋ ๊ฒ์ด ๊ทธ๋ ๊ฒ ์ด๋ ต์ง ์์ ๊ฒ์ ๋๋ค.
๋๋ ๋ค์๊ณผ ๊ฐ์ด renderToString์ ์ต์
์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
renderToString(Component, {async: true})
@nmaro ๊ทธ๋ ๊ฒ ํ๋ฉด ์ ๊ณต๋ ์ต์ ์ ๋ฐ๋ผ ํจ์์ ๋ฐํ ์ ํ์ด ๋ฌ๋ผ์ง๋๋ฐ, ์ด๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ํจ์๋ ํญ์ ๊ฐ์ ์ ํ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@VanCoding ์ฝ๋ ๋ฅผ ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์๊ฐ ์์ต๋๊น?
@VanCoding ๋ฉ์ง๋ค! ํ์ง๋ง ์์งํ ๋ฐ์์ ๋ด๋ถ ๋ ๋๋ง ์๊ณ ๋ฆฌ์ฆ์ ๊ทธ๊ฒ์ ํตํฉํ๋ ๊ฒ์ ์ด๋ ค์ธ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. https://github.com/facebook/react/blob/master/src/renderers/dom/stack/server/ReactServerRendering.js๋ฅผ ํ์ธํ๊ณ ๋ฐ์์ ๋ด๋ถ์์ ๊ธธ์ ์์ต๋๋ค... IMO์์ ๋๊ตฐ๊ฐ์ ์๊ฒฌ์ด ์ ๋ง ํ์ํฉ๋๋ค. ํต์ฌ.
@sedubois ์ผ๋ฐ renderToString ํจ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ฒ๋ผ ํจ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ฌธ์์ด์ ์ง์ ๋ฐํํ๋ ๋์ ๋ฌธ์์ด๋ก ํ์ธ๋๋ Promise๋ฅผ ๋ฐํํฉ๋๋ค.
๋ฐ๋ผ์ ์ฌ์ฉํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
var react = require("react");
var renderAsync = require("react-render-async");
var MyComponent = require("./MyComponent");
renderAsync(react.createElement(MyComponent,{some:"props"}).then(function(html){
console.log(html);
});
์ด๋ก ์ ์ผ๋ก ๊ธฐ์กด์ ๋ชจ๋ ๋ฐ์ ๊ตฌ์ฑ ์์๋ฅผ ์ผ๋ฐ renderToString๊ณผ ๋์ผํ ๋ฐฉ์์ผ๋ก ๋ ๋๋งํ ์ ์์ด์ผ ํฉ๋๋ค. ์ ์ผํ ์ฐจ์ด์ ์ ๋น๋๊ธฐ ๊ตฌ์ฑ ์์๋ ์ง์๋๋ค๋ ๊ฒ์ ๋๋ค.
@nmaro ๋ง์ต๋๋ค. ๋์์ด ๋ ๊ฒ์ ๋๋ค.
์ด์ ๋ํ ์ํ๋ ๋ฌด์์ ๋๊น?
@firasdib ์ฐ๋ฆฌ๋ ์ฌ์ ํ ์ผ๋ถ ๋ฐ์ ๊ฐ๋ฐ์๊ฐ ์๊ฒฌ์ ์ ์ํ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๊ณ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
+1
Google ์ธ๋ฑ์ฑ ๋ฌธ์ ๋ SSR์ ์๊ตฌํ๋ฉฐ ์๋์ ์ค๋ช ๋ ๋ชจ๋ ์ง์ ์ฐ๋ฆฌ๊ฐ ์ฒ๋ฆฌํด์ผ ํ๋ฏ๋ก ์ด ๋ฌธ์ ๋ React๊ฐ ์ผ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์ฑ๊ณตํ๊ธฐ ์ํด ๋งค์ฐ ์ค์ํฉ๋๋ค.
JavaScript๊ฐ Promise๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ์ ์ ํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค๋ฉด ์ ์ฒด ๋น๋๊ธฐ ๋ ๋๋ง์ด ํ์ํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ ์จ๋ฅผ ๋ํ๋ด๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ ๋ก๋๋ฅผ ๋๊ธฐ์(SSR์ ๊ฒฝ์ฐ) ๋๋ ๋น๋๊ธฐ์(์ค์ ์น ๋ธ๋ผ์ฐ์ ์ ๊ฒฝ์ฐ)์ผ๋ก ์ง์ ํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ ๋ก๋ ๋ก์ง์ ๋ชจ๋ โโReact ๊ตฌ์ฑ ์์์ ์์ฑ์์์ ์ฝ์์ ์์ํ ์ ์๊ณ componentWillMount์์ ๋๊ธฐํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ๋ด๊ฐ ์ดํดํ๋ ๋ฐ์ ๊ฐ์ด React ๊ฐ๋ฐ์๋ componentWillMount์ ์ ์ฉ์ฑ์ ์์ฌ์ ํ์ํ๊ณ ์์ฑ์๊ฐ ๋ชจ๋ ์์ ์ ์ํํ๋๋ก ๊ถ์ฅํ์ต๋๋ค. ์ด๋ ์ชฝ์ด๋ ์๋ํฉ๋๋ค.
์ผ๋ถ ์ฌ๋๋ค์ ๊ตฌ์ฑ ์์๋ฅผ ์์ ๋ณด๊ธฐ๋ก ๋ง๋๋ ๊ฒ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค๊ณ ์ฃผ์ฅํ์ต๋๋ค. ๋ถ๋ถ์ ์ผ๋ก ๋ง์ต๋๋ค. ๋ถํํ๋ ์ด๊ฒ์ ๋ ๋๋ง ํธ๋ฆฌ๊ฐ ์๋ฃ๋ ๋๊น์ง ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ ์ง ๋ชจ๋ฅด๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ์๋ ์๋ํ์ง ์์ต๋๋ค.
๋ฌธ์ ์ ํต์ฌ์ ๋ ๋๋ง ๊ธฐ๋ฅ์ด DOMTree์ ์ถ๊ฐํ ๊ตฌ์ฑ ์์๋ฅผ ์ ํํ๋ ๋ ผ๋ฆฌ๋ฅผ ๊ฐ์ง ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ด React๊ฐ ์๋ฒ ์ธก ๋ ๋๋ง์ ๋งค์ฐ ๊ฐ๋ ฅํ๊ณ ์ ํฉํ์ง ์์ ์ด์ ์ ๋๋ค.
IMO์ ์ง์ ํ ์๋ฃจ์ ์ ๋ชจ๋ ๋ฐํ๋ ๋ฐ์ดํฐ ๋ก๋ฉ ์ฝ์์ react๋ก ๋ฑ๋กํ ์ ์๋ ๊ฒ์ ๋๋ค. ๋ชจ๋ ๋ฐ์ดํฐ ๋ก๋ ์ฝ์์ด ์๋ฃ๋๋ฉด ๋ฐ์์ด ๋ ๋๋ง ๊ฒฐ๊ณผ๋ก ์ฐ๋ฆฌ๋ฅผ ๋ค์ ํธ์ถํฉ๋๋ค. ์ฌ๊ธฐ์๋ ์ฌ๋ฌ ๊ฐ์ง ์๋ฏธ๊ฐ ์์ต๋๋ค.
๊ทธ ๊ฒฐ๊ณผ ๋น ๋ฅด์ง ์์ ํ๋ก์ธ์ค๋ก ์๋ฒ ์ธก์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํจ์ฌ ๋ "์ง์ค์ ์ผ๋ก" ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
๋ฐ๋ผ์ ๋๋ ์ฌ์ ํ ์ผ์ ๋๋ด๊ธฐ ์ํด ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ๋ฅผ ์์์ํฌ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์๊ฐํ๊ณ ์์ต๋๋ค. :)
๊ทธ ๋์ ๋น๋๊ธฐ ๋ฐ์ดํฐ ๋ก๋ฉ ํ๊ฒฝ์์ SSR์ ํด๊ฒฐํด์ผ ํฉ๋๋ค.
์ด ๋ชจ๋ธ์ ํน์ ๋์์ธ ์ํคํ ์ฒ์ ์ฝ๋งค์ด์ง ์์ต๋๋ค. ํ๋ญ์ค/๋ฆฌ๋์ค๊ฐ ์ฝ๊ฐ ๋์์ด ๋ ๊ฒ ๊ฐ์ง๋ง ๋ด ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฆฌ๋์ค ๋ชจ๋ธ์ ํฌ๊ธฐํ๊ธฐ ๋๋ฌธ์ ํ์คํ์ง ์์ต๋๋ค.
์ด ๋ชจ๋ธ์ ๋ฌธ์ ๋ ์์ ํญ๋ชฉ #1์ ๋๋ค. ๊ฐ๋จํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ชจ๋ ๋ฐ์ดํฐ ๋ก๋ฉ ํธ์ถ์ ์๊ณ ์์ต๋๋ค. ๋ ๋ฆฝ์ ์ธ "๋ชจ๋"์ด ์๋ ๋ณต์กํ ์์ฉ ํ๋ก๊ทธ๋จ์์ ์ด ๋ชจ๋ธ์ ์๋ React ๊ตฌ์ฑ ์์ ํธ๋ฆฌ์ ๋ ๋๋ง ๋ ผ๋ฆฌ์ ์ผ์ข ์ ๋ณต์ ๊ฐ ํ์ํฉ๋๋ค.
render() ํจ์์ ์ด๋ฏธ ์์ฑ๋ ๋ ผ๋ฆฌ๋ฅผ ๋ฐ๋ณตํ์ง ์๊ณ ๋ณต์กํ ํ๋ก์ ํธ์์ SSR์ด ์ด๋ป๊ฒ ์๋ํ๋๋ก ๋ง๋ค ์ ์๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. Flux๊ฐ ํด๊ฒฐ์ฑ ์ด ๋ ์ ์์ง๋ง ๊ฒฝํ์ด ์์ด์ ํ์ ํ ์ ์์ต๋๋ค.
ํญ๋ชฉ #1 ๊ตฌํ์ด ๋ชจํธํฉ๋๋ค. react-router ์์ ์์ ์ฐ๋ฆฌ๋ ๋ผ์ฐํฐ๋ก ํด๋น ๊ฒฝ๋ก์ ์ํ ์ต์์ ๊ตฌ์ฑ ์์๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค. ๋ค์ ๊ตฌ์ฑ ์์๋ฅผ ์ธ์คํด์คํํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
app.use(function(req, res, next) {
match({ routes, location: req.url }, (error, redirectLocation, renderProps: any) => {
if (error) {
res.status(500).send(error.message)
} else if (redirectLocation) {
res.redirect(302, redirectLocation.pathname + redirectLocation.search)
} else if (renderProps) {
// You can also check renderProps.components or renderProps.routes for
// your "not found" component or route respectively, and send a 404 as
// below, if you're using a catch-all route.
console.log("renderProps", renderProps)
for (let eachComp of renderProps.components) {
// create an instance of component
// ask component to load its data
// store data loading promise in a collection
console.log("eachComp: ", eachComp)
}
res.status(200).send(renderToString(<RouterContext {...renderProps} />))
} else {
res.status(404).send('Not found')
}
})
});
๋ฐ๋ผ์ ์ต์์ ๊ตฌ์ฑ ์์๋ ๋ ์ด์ "์์ํ" ๊ตฌ์ฑ ์์๊ฐ ์๋๋๋ค. ์ด๋ฌํ ๊ตฌ์ฑ ์์๋ ์ด์ ๋ฐ์ดํฐ ๋ก๋๋ฅผ ํธ๋ฆฌ๊ฑฐํ๋ ๊ธฐ๋ฅ์ผ๋ก ์ธํด ์ต์์ ์ปจํธ๋กค๋ฌ ์ญํ ์ ํฉ๋๋ค. Flux ๋ชจ๋ธ์ ๋ ์ด์ ๊ฐ์ ๋์ง ์์ต๋๋ค. ๋จ์ํ ๋ฐ์ดํฐ ๋ก๋ ๊ธฐ๋ฅ ์ฐ๊ฒฐ์ ๋ํ ๊ฒฝ๋ก๋ฅผ ๋ค๋ฅธ ๋ชจ๋๋ก ์ด๋ํฉ๋๋ค.
๋ถํํ๋, ์์ ์ปจํธ๋กค๋ฌ์ ์์์ ์ด ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ณ์ ๋ก๋ํ๋ฉด ๋ฐ์ ๋ ๋๋ง ๋ชฉ์ ์ผ๋ก ์์ฑ๋ ๊ฐ์ฒด ๊ทธ๋ํ๊ฐ ์ค๋ณต๋ฉ๋๋ค. ์ผ์ ๋จ์ํ๊ฒ ์ ์งํ๋ ค๋ฉด(๊ฐ๋ฅํ ๊ฒฝ์ฐ) ๋ชจ๋ ๋ฐ์ดํฐ ๋ก๋๋ฅผ ์ต์์ ์ปจํธ๋กค๋ฌ ์์ค์ ๋ฃ์ด์ผ ํฉ๋๋ค.
๊ทธ๊ฒ์ด ๋ด๊ฐ ๋ณด๋ ๊ฒ์ ๋๋ค.
์ด๋ฌํ SSR์ ์๋ฏธ๋ฅผ ๊นจ๋ฌ์๋ค๋ฉด Google ์ธ๋ฑ์ฑ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ํ React์ ์ ์ฉ์ฑ์ ๋ํด ๋ ๋ฒ ์๊ฐํ์ ๊ฒ์ ๋๋ค. ์๋ง๋ ํ๋ญ์ค๊ฐ ์๋ฃจ์ ์ผ ์ ์์ง๋ง ํ๋ญ์ค๋ ๋จ์ํ React ์ ํ๋ฆฌ์ผ์ด์ ๋ณด๋ค ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ฒด ์์ค์ผ๋ก ๋ ๋ณต์กํ๊ฒ ๋ง๋ญ๋๋ค. ๋ ๊ฑฐ๊ธฐ์ ๊ฐ๋ณธ ์ ์์ด. ๊ฐ๋จํ ๋ฐ์ดํฐ ๋ก๋ ๊ธฐ๋ฅ ๋์ ์ฌ๋ฌ ํ์ผ์์ ๋ด ๋ ผ๋ฆฌ๋ฅผ ์ถ์ ํด์ผ ํฉ๋๋ค. ์ด๋ก ์ ์ธ ์์ค์์ ํ๋ก์ ํธ๋ฅผ ์คํํ๊ธฐ ์ ๊น์ง๋ ์ ๋ง ์ข์ ๋ณด์์ต๋๋ค. ์๋ก์ด ์ฌ๋๋ค์ ์์ํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช์์ต๋๋ค. ์ฝ๋ ๊ธฐ๋ฐ์์ redux๋ฅผ ๊ฐ์ ธ์จ ํ์๋ ๊ทธ๋ฐ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๋ชจ๋ UI ๋์์ธ์ ๋ณต์ก์ฑ์ ๋ํ ๋ต์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค :)
์ด๋ฒ ์ฃผ React Conf ์์ React Fiber(React 16)๊ฐ ๋์จ ํ ๋ค์ ์์ ์ ๊ณํํ๊ณ ์์ต๋๋ค(React 17๋ก ์ถ์ ).
๋น๋๊ธฐ React ์๋ช ์ฃผ๊ธฐ ๋ฉ์๋๊ฐ ์ฌ ์ ์์์ ์๋ฏธํฉ๋๊น?
๊ธ์, ์ฌ์ ์ฌ๋ฃ๋ ๋๋ถ๋ถ ๋ ๋น ๋ฅด๊ณ ๋ถ๋๋ฌ์ด ์ฌ ๋ ๋๋ง์ ๊ดํ ๊ฒ์ด ์๋๋๊น? ์๋ฒ์์๋ ํ ๋ฒ๋ง ๋ ๋๋งํ๋ฏ๋ก ์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ด ์๋ฒ ์ธก ๋ ๋๋ง์ ์ํฅ์ ๋ฏธ์น ์ง ํ์คํ์ง ์์ต๋๋ค.
@VanCoding ์ ์ฝ๊ฐ ๋ถ๋ถ๋ช ํ ์์ ๋ฉ์์ง๋ฅผ ์ ๋ฐ์ดํธํ์ต๋๋ค. ๋๋ ์ฌ์ ๊ฐ ๋๊ธด ์ดํ์ ๋ํ ๊ทธ๋ค์ ๊ณํ์ ์๋ฏธํ์ต๋๋ค.
๋์ฒ๋ผ ์ฌ๊ธฐ์ ๋์ฐฉํ ์ฌ๋๋ค์ ์ํด ๋์์ด ๋ ์ ์๋ ๋ฐ์์ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ ์ ๊ตฌํ์ ๋ง๋ค์์ต๋๋ค.
https://github.com/siddharthkp/reaqt
ํค๋ ์๋ฒ์์๋ง ์คํ๋๋ asyncComponentWillMount์ ๋๋ค. ์ฌ๊ธฐ์ ์ธ๊ธ๋ ๋ฌธ์ ๋ฅผ ํผํ๊ธฐ ์ํด ๋ชจ๋ ๊ตฌ์ฑ ์์๊ฐ ์๋๋ผ ์ง์ ์ ๊ตฌ์ฑ ์์์๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค.
@siddharthkp ๊ทํ์ ๊ตฌ์ฑ ์์๊ฐ ํด๊ฒฐํ๋ ค๊ณ ํ๋ ๊ฒ์ด ๋ฌด์์ธ์ง ์ ๋ง๋ก ์ ์ ์์ต๋๊น? ์ต์์ ์ ํ๋ฆฌ์ผ์ด์ React ๊ตฌ์ฑ ์์์ ๋ํด asyncComponentWillMount๋ง ์ง์ํ๋ค๋ฉด ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๊น? ์ธ๋ถ์์ ๊ทธ ์ฝ์์ ํด๊ฒฐํ ๋ค์ render๋ฅผ ํธ์ถํ ์ ์์ต๋๊น? ์๋๋ฉด ๋ด๊ฐ ๋ญ๊ฐ๋ฅผ ๋์ณค๋์?
@fkrauthan
์ธ๋ถ์์ ๊ทธ ์ฝ์์ ํด๊ฒฐํ ๋ค์ render๋ฅผ ํธ์ถํ ์ ์์ต๋๊น?
๋น์ ์ด ์ณ์ต๋๋ค. ๊ทธ๊ฒ์ด ์ ํํ ํ๋ ์ผ์ ๋๋ค.
๋งค๋ ฅ์ ํ๋์ ๋ช ๋ น์ผ๋ก ๋น๋๊ธฐ ssr(+ ์ฝ๋ ๋ถํ + hmr)์ ์ป์ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ssr์ด ์ฝ์ง ์๊ธฐ ๋๋ฌธ์ ๊ตฌํํ์ง ์๋ ์ฌ๋๋ค์ ๋ง์ด ๋ณด์๊ณ ๊ทธ๊ฒ์ด ๋๊ธฐ์์ต๋๋ค.
์ต์์ ์ ํ๋ฆฌ์ผ์ด์ React ๊ตฌ์ฑ ์์์ ๋ํด์๋ง asyncComponentWillMount๋ฅผ ์ง์ํฉ๋๋ค.
ํ๋์ ์์ฉ ํ๋ก๊ทธ๋จ ๊ตฌ์ฑ ์์๊ฐ ํ์ํ์ง ์์ต๋๋ค. ํ์ด์ง/ํ๋ฉด/์ง์ ์ ๋ณ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ( ์ฌ๊ธฐ์ ์ฌ๋ฌ ์ง์ ์ ์ ํ๋ณด)
ํจํด์ ์๋์ ์ ๋๋ค. ํธ๋ฆฌ์ ๋ชจ๋ ๊ตฌ์ฑ ์์๊ฐ ์์ฒด ๋ฐ์ดํฐ๋ฅผ ์ํ๋ ๊ฒฝ์ฐ ์ฑ๋ฅ์ ๋์ ํจํด์ ์กฐ์ฅํ ์ ์์ต๋๋ค. ์ต์์ ๊ตฌ์ฑ ์์์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์ props๋ก ์์์๊ฒ ์ ๋ฌํ๋ฉด ๋ฐ์ดํฐ๊ฐ ๊ณ์ ํ์ธ๋ฉ๋๋ค.
@siddharthkp ๊ทํ์ repo๋ Next.js(React Conf BTW์์๋ ๋ฐํ๋จ)๋ณด๋ค ์ด๋ป๊ฒ ํฅ์๋ฉ๋๊น?
https://github.com/zeit/next.js
์ด์จ๋ ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ๋ ผ์๋ IMHO์์ ๋ฒ์ด๋ ์ฃผ์ ์ด๋ฉฐ, ์ฐ๋ฆฌ๊ฐ ๊ด์ฌ์ ๊ฐ๋ ๊ฒ์ React ์์ฒด ๋ด์์ ์ง์ํ๋ ๊ฒ์ ๋๋ค.
ํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ๋ ผ์๋ ์ฃผ์ ์์ ๋ฒ์ด๋ IMHO์ ๋๋ค. ์ฐ๋ฆฌ๊ฐ ๊ด์ฌ์ ๊ฐ๋ ๊ฒ์ React ์์ฒด ๋ด์์ ์ง์ํ๋ ๊ฒ์ ๋๋ค.
์์ ํ ๋์ ํด. reaqt ๋ฌธ์ ์ ํน์ ์ง๋ฌธ์ ๋ํด ๋ ผ์ํ ์
์ด์ ๋ํ ์ฌ์ฉ ์ฌ๋ก๋ react-native ๋ฐ react-native-vector-icons๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ๋๋ Promise์์ ๋ฐ์ ๋ฐ์ดํฐ์ ์ํด ์ปดํฌ๋ํธ์ prop์ด ๊ฒฐ์ ๋๊ธฐ๋ฅผ ์ํฉ๋๋ค.
const AsyncUser = props => fetchUser()
.then(data => (
<User {...data} />
))
์ง์๋๋ค๋ฉด ๋ง์ ๋ณต์กํ ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค๊ณ ์๋ก์ด ๋น๋๊ธฐ ํจํด์ ์ด ์ ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ฐ๋ฆฌ๋ ๋์ผํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ssr์ ์ํํ๊ณ ์ถ์ต๋๋ค. ์์ธก ์ํ์ ๊ฒ์ํ ๋ฟ๋ง ์๋๋ผ componentWillMount์์ ์์ ์ผ๋ก ๊ฐ์ ธ์จ ์ฝํ ์ธ ๋ ๊ฒ์ํ๊ณ ์ถ์ต๋๋ค. ์ํ์ด ์ค๋น๋ ๋๊น์ง ๊ธฐ๋ค๋ ธ๋ค๊ฐ ์ํ์ ๋ฌธ์์ด๋ก ๋ ๋๋งํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ ๋๊น?
์ด ๊ธฐ๋ฅ์ด ์ ์ฉํ๋ค๊ณ ์๊ฐํ๋ ์ฌ๋์ด ์์ผ๋ฉด ๊ตฌ์ฑ ์์๊ฐ ๋ ๋๋ง๋ ๋ ์๋ฒ์ ํด๋ผ์ด์ธํธ๊ฐ ๋ชจ๋ ๋ ๋๋ง๋ ๋ ์คํ๋๋๋ก ์ฝ์ ๋ฐํ ํจ์๋ฅผ ๊ตฌ์ฑ ์์์ ๋ฐ์ธ๋ฉํ ์ ์๋ react-frontload ๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฑํ์ต๋๋ค.
์ด ํจ์๋ ์๋ฒ ๋ ๋์์ '๋๊ธฐ์ ์ผ๋ก' ์คํ๋์ง๋ง(์ค์ ๋ก๋ ๊ทธ๋ ์ง ์์ ;-) ์ต์ข ๊ตฌ์ฑ ์์ ๋ ๋๋ ํด๊ฒฐ๋ ๋๊น์ง ์ฐจ๋จ๋๊ณ ํด๋ผ์ด์ธํธ ๋ ๋์์๋ ์ ์์ ์ผ๋ก ๋น๋๊ธฐ์์ผ๋ก ์คํ๋๋ฉฐ ํ์ด์ง๊ฐ ๋ฐฉ๊ธ ์คํ๋ ๊ฒฝ์ฐ ํด๋ผ์ด์ธํธ์์ ๋ค์ ์คํ๋์ง ์์ต๋๋ค. ์๋ฒ ๋ ๋๋ง. ๋ํ ๊ตฌ์ฑ ์์๋ณ๋ก ์คํ ์์ ์ ๋ณด๋ค ์ธ๋ฐํ๊ฒ ์ ์ดํ๊ธฐ ์ํด ์ง์ ํ ์ ์๋ ์ต์ ์ด ๋ ์์ต๋๋ค.
๋ฐ์ดํฐ ๋ก๋ฉ์ ์ ๋ง ์ ์ฉํฉ๋๋ค. ์ ๊ฐ ํด๊ฒฐํ๊ธฐ ์ํด ์์ฑํ ์ฌ์ฉ ์ฌ๋ก์ ๊ฑฐ์ ๋น์ทํฉ๋๋ค. ๊ทธ๊ฒ์ ๋ฐ์ผ๋ก ์๋! ๐
<AsyncComponent
delayRendering={LoadingComponent}
>
{/*return a promise that returns a component here*/}
</AsyncComponent>
๋ฐ์ดํฐ๊ฐ ์๋ค๋ ๊ฒ์ ์๊ณ ์๊ธฐ ๋๋ฌธ์ ์์ ์ ๊ทผ ๋ฐฉ์์ผ๋ก ํ ํ์๊ฐ ์๋ ๋ชจ๋ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์๊ฐํด ๋ณด์ญ์์ค.
์ด์ ๋์ฐธํฉ๋๋ค. ์์ง๊น์ง๋ React์ ๋ถ์กฑํ ํ์ ๊ธฐ๋ฅ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ํ ์ 3์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด ์ฃผ์ ๋ฅผ ๋ค๋ฃฐ ์ ์๋๋ผ๋ ์ด๋ ๋ด๋ถ์์ ์ง์ ๊ฐ์ ธ์์ผ ํ๋ค๋ ๋ฐ ๋์ํฉ๋๋ค.
๋๋ ๊ตฌํ์ ์๊ฐํด ๋์ต๋๋ค. https://github.com/timurtu/react-render-async
์์ฃผ ์ข์ ๋น๋๊ธฐ ์ปดํฌ๋ํธ ์ธํฐํ์ด์ค, @timurtu.
...์ฌ๋ฌ๋ถ, ์ด ์ค๋ ๋์ ๋งค์ฐ ์ง์ ์ ์ธ ๊ด๋ จ์ด ์๋ ์ฌ๋ฌ ๊ฐ์ง ์ฌํญ์ด ์์ผ๋ฏ๋ก ์ฌ๊ธฐ์ ์ฐธ์ฌํ๊ณ ์ถ์์ต๋๋ค. ์ ๋ ์ค๋ซ๋์ ์ด ์ค๋ ๋๋ฅผ ์ถ์ ํด ์์ต๋๋ค.
babel-plugin-universal-import
+ webpack-flush-chunks (๋ฐ extract-css-chunks-webpack-plugin )๋ ์ด ๋ฌธ์ ๋ฅผ ์ค์ ๋ก ํด๊ฒฐํ๋ ํจํค์ง ์ ํ๊ตฐ์
๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฒ์์ผ๋ก. ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฒ์์ ๊ตฌ์ฑ ์์๋ฅผ ๋๊ธฐ์์ผ๋ก ๋ ๋๋งํ ์ ์์ง๋ง ๋ ์ค์ํ ๊ฒ์ ํด๋ผ์ด์ธํธ์์ ์ด๊ธฐ ๋๊ธฐ์ ๋ ๋๋ง์ ์ํด ํด๋ผ์ด์ธํธ๋ก ๋ ๋๋ง๋ ์ ํํ ์ฒญํฌ๋ฅผ ์ ์กํ๋ ๊ฒ์
๋๋ค. webpack ํ๋ฌ๊ทธ์ธ์ ํตํด CSS ์ฒญํฌ ์คํ์ผ์ํธ๋ฅผ ์ป์ ์๋ ์์ต๋๋ค. ์ด๊ฒ์ @timurtu๊ฐ ๊ณต์ ํ ๊ฒ๊ณผ main.js
๋ก๋, ๊ตฌ๋ฌธ ๋ถ์, ํ๊ฐ, ๋ ๋๋ง ๋ฐ ๋ช ์ด ํ์ ๋์ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์์ฒญํด์ผ ํ๋ ๋ง์ ๊ตฌ์ฑ ์์์ ๋ค๋ฆ
๋๋ค. ์ด๋ค์ ์คํ์ผ์ด ์ง์ ๋์ง ์์ ์ฝํ
์ธ ์ ํ๋์(FOUC)๋ฅผ ํด๊ฒฐํ์ง๋ง ์๋ฒ์์ ๋ ๋๋ง๋ ์ ํํ ์ฒญํฌ๋ฅผ ํ์ด์ง์ ํฌํจํ์ง ์๋ ์๋ฃจ์
์
๋๋ค. Universal( ๋ด ํจํค์ง ์ ํ๊ตฐ์ ์ด๋ฆ)์ ์ฌ์ฉํ๋ฉด ๊ธฐ์กด ์น์ฑ์ฒ๋ผ ์๋ํ๋ ๋๊ธฐ์ ๋ฐฉ์์ผ๋ก TTI(Time to Interactive) ๋ฅผ ํจ์ฌ ๋น ๋ฅด๊ฒ ์ํํ ์ ์์ต๋๋ค. React Universal Component 2.0 & babel-plugin-universal-import ์์ ์ด์ ๋ํด ์์ธํ ์์๋ณผ ์ ์์ต๋๋ค.๊ฒฝ๋ก ์์ค ๋ ๊ตฌ์ฑ ์์ ์์ค ์ฅ๋จ์ ์ ๋ค๋ฃจ์ง ์์๋ค๋ ๊ฒ์ ์๊ณ ์์ง๋ง ์ฒซ ๋ฒ์งธ ๋งํฌ๋ ์ฃผ๋ก ๊ทธ๊ฒ์ ์ค์ ์ ๋ก๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ (๋ณ๋ ฌ์ด ์๋) ์์๋๋ก ๊ฐ์ ธ์์ผ ํ๋ ์ค์ฒฉ ๊ตฌ์ฑ ์์๊ฐ ์๋ ๊ฒฝ์ฐ SSR์ ์ข์ง ์์ ๊ตฌ์ฑ ์์ ์์ค์ผ๋ก ์์ฝ๋ฉ๋๋ค. ๊ฒฝ๋ก๋น ํ๋์ ๊ฐ์ ธ์ค๊ธฐ๋ง ์ฌ๋ฐ๋ฅด๊ฒ ์ํํ ์ ์๋ค๋ฉด componentDidMount
์์ ์ํํ๋ ๋์ ๋ฐ์ดํฐ ์ข
์์ฑ์ ๊ฒฝ๋ก ์ํฐํฐ์ ์ฒจ๋ถํ์ฌ ๊ณ์ฝ์ ๊ณต์ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์์ ๋ง์ ๋ค๋ฅธ ์ฌ๋๋ค๋ ์ด์ ๊ฐ์ ๊ฒฐ๋ก ์ ๋๋ฌํ์ต๋๋ค. Redux-First Router ๋ Redux๋ฅผ ์ฆ๊ฒ๊ฒ ์์
ํ ์ ์๋๋ก ํ๋ ์ผ์ข
์ "๊ณ์ฝ"์ ๋ฐ๋ผ ์ด๊ฒ์ ๋งค์ฐ ํ๋ฅญํ๊ฒ ๊ณต์ํํฉ๋๋ค.
Redux-First Router ๋ ๋ง์ ๊ธฐ์กด ํจ๋ฌ๋ค์์ ๋ค์ ์๋ก ๋ง๋ค์ง๋ง ๋๋๊ฒ๋ Redux ์์ฝ์์คํ ์์ ๋๋ฝ๋ ๋ถ๋ถ์ผ๋ก ๋ฑ ๋ง์ต๋๋ค. Redux์ ์ํฌํ๋ก์ ๊ณ ์ ํ ๋ผ์ฐํฐ๋ฅผ ์ํ๋ค๋ฉด Redux-First Router๋ฅผ ์ฌ์ฉํด ๋ณด์ญ์์ค. ๋น๊ต์ ์๋กญ๊ณ ์คํ ์์ค๋ฅผ ์ฒ์ ์ ํ๋ ์ฌ๋์ด์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก 1๋ ๋์ ์์ ํ ์์ ์ด๋ฉฐ ์ถ์๋ ์ง 2๊ฐ์ ๋ง์ ๋ง์ ๊ด์ฌ์ ๋ฐ์์ต๋๋ค. ์ฌ๋๋ค์ ๊ทธ๊ฒ์ ์ฌ๋ํฉ๋๋ค. ๊ผญ ํ๋ฒ ๋ณด์๊ณ ๊ฒฐ์ ํ์๊ธธ ๋ฐ๋๋๋ค :).
๋ค์์ React Router๋ณด๋ค Redux๋ฅผ ์ํ ํจ์ฌ ๋ ๋์ ์๋ฃจ์
๊ณผ ๋ํ ์ฐ์ํ Redux-Little Router๊ฐ ๋ถํํ๋ ๋์น ๋ฐฉ์์ผ๋ก ๋น์ ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ป๋ ๋ฐฉ๋ฒ์ ์ค๋ช
ํ๋ ์ถ์ ๊ธฐ์ฌ์ด๊ธฐ๋ ํฉ๋๋ค.
์ฌ์ ์ถ์: Redux-First ๋ผ์ฐํฐ โ Redux-Little-Router๋ฅผ ๋์ด์ ๋จ๊ณ
RLR๊ณผ RFR์ ์ฃผ์ ์ฐจ์ด์ ์ RFR์ด ํญ์ LOCATION_CHANGED
๋์ ์ ๊ฒฝ๋ก๋น ๋ค๋ฅธ ์์
์ ํ(์: URL ๋ณ๊ฒฝ)์ ์ ๋ฌํ๋ค๋ ๊ฒ์
๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ค๋ฅธ ์์
๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฆฌ๋์์์ URL ๋ณ๊ฒฝ์ ๊ณ ์ ํ ์ ํ์ผ๋ก ์ ํํ ์ ์์ต๋๋ค. ์๊ฒ ๋ณด์ผ ์ ์์ง๋ง ํฐ ์ฐจ์ด๋ฅผ ๋ง๋ญ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ Redux ๋๋์์๋ ๋ถํ์ํ <Route />
์ปดํฌ๋ํธ๊ฐ ํ์ํ์ง ์์ต๋๋ค. Redux-First Router ๊ฐ thunks
๊ฒฝ๋ก์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์์ React Native, React Navigation, ์ฝ๋ ๋ถํ , ํ๋ฆฌํ์นญ ๋ฑ์ ์ด๋ฅด๊ธฐ๊น์ง ์ง์ํ๋ ๊ธฐ๋ฅ์ ๋ฐฉ๋ํ ๋ชฉ๋ก๋ ์์ต๋๋ค.
์ฌ๋๋ค์ ์๊ฐ์ ๋ฃ๊ณ ์ถ์ต๋๋ค.
@faceyspacey ๊ฐ์ฌํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก props๋ฅผ ์ค์ ํ๋ ค๋ ๊ฒฝ์ฐ react-native-vector-icons
๊ฐ ์์ด์ฝ์ ์ฝ์์ผ๋ก ๋ฐํํ ์ ์๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๊ฒ ๊ฐ์ต๋๋ค. ํ์คํ ์ฌ๋ฌผ์ ๋ณด๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด์ง๋ง ๋น๋๊ธฐ ๊ตฌ์ฑ ์์๋ฅผ ์ํ์ ์ฐ๊ฒฐํ๋ componentWillMount
๋๋ redux X_GET_START
, X_GET_END
๋ฐ X_GET_ERROR
์์
์์ฉ๊ตฌ๋ฅผ ์ค์
๋๋ค. ๊ตฌ์ฑ ์์๋ฅผ ๋ ๋๋งํ๊ธฐ ์ํด ํด๋น ์์ฒญ์ ํ ๋ฒ๋ง ์ํํ๋ ค๋ ๊ฒฝ์ฐ. ๋ฐ์ดํฐ ํด๋ง๊ณผ ๊ฐ์ ์์
์ ์ํํ๋ ๊ฒฝ์ฐ ์ํ ์ ์ฅ ๋ฐ redux๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ํฉ๋ฆฌ์ ์ผ ์ ์์ต๋๋ค.
@faceyspacey ๊ฒฝ๋ก ์์ค์ ๋ํด ๋ง์ ์์ง๋ง ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ๋ง ์์กดํ๊ณ ์ฃผ๋ณ์ ๋ค๋ฅธ ๋ชจ๋ ๊ฒ์ ๋๊ธฐ์ ์ผ๋ก ๋ ๋๋งํ๋ ์์ ๊ตฌ์ฑ ์์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ข์ง ์์๊น์?
๋ ๋์? ์ด๋์? React Native์์? Facebook๊ณผ ๊ฐ์ ๋๊ท๋ชจ ์กฐ์ง์์ React Native ์ฑ์ ์ฌ์ฉํ์๋์?
์๋ง๋ React Native์์์ ๊ฒ์ ๋๋ค. ๋ด๊ฐ ๋ณด๊ธฐ์๋ SSR์ด ์์ ๋ ๋ ผ์์ด ์์ต๋๋ค. ๋ค์ ํ ๋ฒ, ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ํํ ์ ์๋ ํ๋์ ๊ตฌ์ฑ ์์๋ก ์ ํํ์ง ์๋ ํ ์์ฒญ๋น ์ฌ๋ฌ ๊ฐ์ ธ์ค๊ธฐ ์์ด ์ํ๋ ์์ ์ ๋ถ๊ฐ๋ฅํฉ๋๋ค. ์ด ์์ ์์ ๊ฒฝ๋ก ์ํฐํฐ์์ ๊ณ์ฝ์ ๊ณต์ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
React Native์ SPA๋ ๋ฌผ๋ก ์ ๋๋ค. ๊ทธ๋ฌ๋ ๋ด์ฅ๋ ๋ฐ์ดํฐ ๋์ด ์๋ ๊ตฌ์ฑ ์์๋ฅผ ํ ์คํธํ๋ ๊ฒ์ ๊ณ ํต์ค๋ฌ์ด ์ผ์ ๋๋ค. Apollo์๋ ์ฌ๊ธฐ์ ๋ช ๊ฐ์ง ํญ๋ชฉ์ด ์์ง๋ง ๋ง์ง๋ง์ผ๋ก ๋ฐ์ดํฐ ์ ๊ตฌ์ฑ ์์ ํ ์คํธ๋ฅผ ์ ๋ง ์ฌ๋ฐ๋ฅด๊ฒ, ์ฆ ๋งค๋๋ฝ๊ฒ ํ๊ธฐ ์ํด ๊ธด ํ ์ผ ๋ชฉ๋ก์ด ์๋์ง ํ์ธํ์ต๋๋ค. ์ค์ ํ๊ณ ์กฐ๋กฑํ๊ธฐ ์ฌ์ด ํ๋์ ์ ์ฅ์๊ฐ ์๋ ์ค์ ์ ์ ํธํฉ๋๋ค. ๋ชจ๋ ํ ์คํธ์์ ๊ทธ ๋ฐฉ๋ฒ์ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ๊ฑฐ๊ธฐ์์ ๊ตฌ์ฑ ์์ ํ ์คํธ๋ ์ค๋ ์ท ์ดฌ์์ ํตํ ๊ฐ๋จํ ๋๊ธฐ ๋ ๋๋ง์ ๋๋ค. ๊ตฌ์ฑ ์์์ ๋ฐ์ดํฐ dep๋ฅผ ์ถ๊ฐํ๋ฉด React ํ ์คํธ๊ฐ ๋ ์ง๊ด์ ์ด ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ์ฌ๋๋ค์ ๊ทธ๊ฒ์ ํ๊ณ ๊ทธ๊ฒ์ ์๋ํํฉ๋๋ค. ํ์ค์ด ์ ๊ณ ์ด์ ์ฌ์ฉ์ ์ง์ ์์ ์ฝ๋์ ๋ ๊ฐ๊น์ต๋๋ค. ์ฑ์์ผ ํ๋ ๋ชจ๋ ๋น๋๊ธฐ ๊ตฌ์ฑ ์์์ ๋ํด ์ ์ฌ์ ์ผ๋ก ๋ค๋ฅธ ์ ๋ต์ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๋งค์ฐ ๋ถ๋ช ํ ๋ฐฉ์์ผ๋ก ๋น๋๊ธฐ์ ์ผ๋ก ์ฑ์์ง ์ ์๋ ์ ์ฅ์๋ฅผ ๊ฐ๋ ๊ฒ์ด ๋ ์์ฐ์ ์ ๋๋ค.
SSR์ด ์๊ณ ํ ์คํธ ์ ๋ต์ด ์ํํ๊ณ ๋ฐฉํด๊ฐ ๋์ง ์๋ ๊ฒฝ์ฐ ๊ตฌ์ฑ ์์ ์์ค์ ๋ฐ๋ํ์ง ์์ต๋๋ค. ๋น์ ์ด ๊ฑฐ๋ ๊ธฐ์ ์ด๋ผ๋ฉด ๋ชจ๋ ๊ฐ๋ฐ์๊ฐ ์ต์์ ๊ฒฝ๋ก ๋ ๋ฒจ์ ๊ฑด๋๋ฆด ํ์๊ฐ ์๊ณ ์ ์ฌ์ ์ผ๋ก ๋ค๋ฅธ ๊ฐ๋ฐ์๋ฅผ ์ํด ๊ทธ๊ฒ์ ๊นจ๋จ๋ฆด ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. ์ด๊ฒ์ด FB๊ฐ Relay์ GraphQL์ ํตํด ์ด ๊ฒฝ๋ก๋ฅผ ๊ฐ์ฒํ ์ด์ ์ ๋๋ค. ๋ฌธ์ ์ ์ฌ์ค์ ์ด ๋ฐฐ์ ์ง์ ์ผ๋ก ์ธ๊ณ์์ 100๊ฐ ํ์ฌ๋ง ์๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. ๊ทธ๋์ ์ ๋ ์ฝ๋ก์ผ์ด์ ์ ๋๋ถ๋ถ์ ์ฌ๋/์ฑ/ํ์ฌ์์ ํ์ค๋ณด๋ค ๊ณผ์ฅ๋ ๊ฒ์ผ๋ก ๋ด ๋๋ค. ์ผ๋จ ๋ผ์ฐํธ ์์ค์ ์ดํดํ๊ณ Redux-First Router ์ฒ๋ผ ์ ์ํํ๋ ํจํค์ง๋ฅผ ๊ฐ๊ฒ ๋๋ฉด ๊ตฌ์ฑ์์ด ๋ผ์ฐํธ ์์ค์ ๋ง์ง ์ ์๋ ํ์ ์ํ ์ ๊ทผ ๋ฐฉ์์ ๊ฐ๋ฐํ๊ธฐ๊ฐ ํจ์ฌ ๋ ์ฌ์์ง๋๋ค. ์ฝ๋์๋๋ฐ์ค ํํ์ด์ง์์ ๋ฐ๋ชจ๋ฅผ ํ์ธํ์ธ์.
๊ธฐ๋ณธ์ ์ผ๋ก ์์ ์ด ์ด๋ป๊ฒ ์๋ฃ๋์๋์ง ํ์ธํ๊ณ ๋๋ฉด ๊ทํ์ ์๊ฒฌ์ ๋ฃ๊ณ ์ถ์ต๋๋ค. ์ด๊ฒ์ SPA์์ ๋ช ์ฌํ์ญ์์ค. ๋ฐ๋ผ์ SSR ์์ ์ ๋ํ ๋ฐ๋ชจ ๋ฆฌํฌ์งํ ๋ฆฌ ๋๋ ์์ฉ๊ตฌ ๋ฅผ ๊ฒํ ํด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ์ข์ ์์์ ๋๋ค.
๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ ๋น๋๊ธฐ ๋ ๋ ๋ฉ์๋๋ฅผ ์ง์ํ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค(๋ ๋๋ ์ฝ์์ ๋ฐํํฉ๋๋ค). ๋ฃจํธ ๊ตฌ์ฑ ์์ ๋๊ธฐ ์์ ๊ตฌ์ฑ ์์ ๋ ๋๋ง์ ํ์ฉํ๊ณ ๋ฌผ๋ก ๋ ๋๋ง ๊ฒฐ๊ณผ๋ ์ฝ์์ด ๋ ๊ฒ์ ๋๋ค. ๋๋ https://github.com/3axap4eHko/preact-async-example ์ preact์์ ์ด์ ๊ฐ์ ๊ฒ์ ๊ตฌํํ์ต๋๋ค.
@faceyspacey ์์ ์์ธํ ๋ต๋ณ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ์ ๋ Redux-First Router์ ์์ด๋์ด๊ฐ ์ ๋ง ๋ง์์ ๋ญ๋๋ค. ํ์คํ ์ ๋ชจ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ด์ ๋ณด๋ค ํจ์ฌ ๋ ํฌ๋ช ํ๊ณ ๊นจ๋ํด์ก์ต๋๋ค.
ํฐ ๊ฐ์ฌ๋ฅผ ๋๋ฆฐ๋ค!
@raRaRa ๋ง์์ ๊ฒฝ๋ก ์์ค ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ๋ํ ์ข์ ์ถ์ํ๊ฐ ์์๋ค๋ ๊ฒ์
๋๋ค. React React v3์๋ ์ฝ๋ฐฑ์ด ์์๊ณ v4์๋ ์ฐ์ํ ํจํด(ํนํ react-router-config
ํจํค์ง)์ด ์์ง๋ง ๋ช
ํํ์ง ์๊ณ v4์์ ์ผ๊ธ์ด ์๋๋๋ค. ๊ทธ๊ฒ์ ๋์ค์ ์๊ฐ์
๋๋ค. ๊ทธ๋ฌ๋ ๋ ์ค์ํ ๊ฒ์ Redux์ ์กด์ฌํ์ง ์๋๋ค๋ ๊ฒ์
๋๋ค. ๋ฐ๋ผ์ redux ์ฌ์ฉ์๊ฐ ์์ ํ "๊ฒฝ๋ก ์์ค" ์ถ์ํ๋ฅผ ๊ฐ๊ฒ ๋ ๊ฒ์ ์ด์ ์์ผ ์ฒ์์
๋๋ค.
์ด์ RFR์ ํตํด "๊ฒฝ๋ก ์์ค" ๋ "๊ตฌ์ฑ ์์ ์์ค"์ ์ค์์ฑ์ ๋ํด ๋ค์ ์๊ฐํ๊ฒ ๋ ๊ฒ์ ๋๋ค. Relay ๋ฐ Apollo์ ๊ฐ์ ๊ฒ๋ค์ ๊ตฌ์ฑ ์์์ ๋ํ ๋ฐ์ดํฐ ์ข ์์ฑ์ ํ์ด๋งํ๋ ๊ฒ๊ณผ ๊ด๋ จํ์ฌ ๋ง์ ๊ณผ๋ ๊ด๊ณ ๋ฅผ ๋ง๋ค์์ต๋๋ค. ํ์ง๋ง ์ด ๋ ๊ฐ์ง๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์๋ช ์ฃผ๊ธฐ ์ฒ๋ฆฌ๊ธฐ์์ ์์ ์ ์ํํ์ฌ ์ด๋ ์์ ์์ ์์ฒ์ ์ธ๊ณ์ ๋น ์ง๊ฒ ๋ ๊ฒ์ ๋๋ค. .
๊ทธ๊ฒ์ ๊ฒฐ๊ตญ RFR์ด Apollo์ ๊ฒฝ๋ก ์์ค ํตํฉ์ ๊ฐ๊ฒ ๋ ๊ฒ์ด๋ผ๊ณ ๋งํ์ต๋๋ค. ์์ ์ธ๊ธํ ๋๋ฌธ ์์ธ๋ฅผ ์ ์ธํ๊ณ ๊ตฌ์ฑ ์์ ์์ค์์ ์์ ์ ์ํํ ๋ ์ป์ ์ ์๋ ์ด์ ์
React Native + Apollo์ ๊ฒฝ์ฐ SSR์ด ์์ผ๋ฏ๋ก ์๋ฒ์์ ์์ฐจ์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ์ ์ต๋๋ค. ๊ทธ๋ฌ๋ ํ๋ฉด์ด ๋๋ฌด ์์ ๋ ๊ตฌ์ฑ ์์ ์์ค์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๊ฐ ์ ๋ง๋ก ํ์ํฉ๋๊น? ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ดํฐ ์ธก๋ฉด์์ ๊ฐ "์ฅ๋ฉด"์ ํ์ํ ๊ฒ์ด ๋ฌด์์ธ์ง ์๊ณ ์์ต๋๋ค. ๋ฐฑ๋ง ๊ฐ์ ๊ทธ๋ํ, ์ฌ๋ฌ ํ
์ด๋ธ ๋ฑ์ด ์๋ ๋ฐ์คํฌํ ์น ํจ๋ ๋์๋ณด๋์ ๋ค๋ฆ
๋๋ค. ํ ๊ฐ์ง ์ฌ์ฉ ์ฌ๋ก๋ ์๋ง๋ ๊ตฌ์ฑ ์์ ์์ค์ด ์ดํด๋๊ธฐ ์์ํ๋ ๊ฐ์ฅ ํฐ ์ฃผ์ ์ฅ์์ผ ๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ ๊ฑฐ๊ธฐ์์๋ ๋ชจ๋ ์์ ฏ์ ๋ํ ๋ชจ๋ ์๊ตฌ ์ฌํญ์ ํ ๊ณณ์์ ์ง์ ํ๊ณ Apollo๋ฅผ ํตํด ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ์์ง ์ถฉ๋ถํ ๊ณ ๋ คํ์ง ์์์ง๋ง ๊ธฐ๋ณธ ์์ด๋์ด๋ GraphQL ๋ฐ์ดํฐ ์๊ตฌ ์ฌํญ์ ๊ฒฝ๋ก์ ์ฒจ๋ถํ ๋ค์ ๊ตฌ์ฑ ์์์์ ๋ค๋ฅธ Redux ๋ฐ์ดํฐ์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฐ์ดํฐ์ ์ฐ๊ฒฐํ๋ ๊ฒ์
๋๋ค. ๋ณด๋ค ๊ตฌ์ฒด์ ์ผ๋ก ๋งํ๋ฉด react-redux์ connect
์ Apollo์ ๋๋ฑํ ๊ธฐ๋ฅ์ ๋ชจ๋ ์ ๊ฑฐํ๋ ๊ฒ์
๋๋ค. ๋๋ ๋จ์ง ํ๋๋ฅผ ์ํ๊ณ ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ด ๋ ์์ฒจํ๊ธฐ๋ฅผ ์ํฉ๋๋ค. Apollo๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๊ตฌ์ฑ ์์์์ ์ง์ ์ผ๋ก ์ํ๋ ๊ฒ์ ์ก์ธ์คํ๊ธฐ ์ํด ๋ ๊น์ด ์ค์ฒฉ๋ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํด์ผ ํฉ๋๋ค. ๋น์ ์ ์ผ๋ฐ Redux์ ๊ฒฝ๋ก ์์ค์์ graphql ์ฌ์์ ๋ํ ๊ฒ์ฒ๋ผ ๋ณด์ด๋ ํ ๊ฐ์ง ๋ฐฉ๋ฒ์
๋๋ค.
๋ด๊ฐ ๊ฐ์ ํ ์ดํด๋ดค๊ธฐ ๋๋ฌธ์ ๊ทธ๊ฒ์ ๋ํด ์ด์ผ๊ธฐํ๊ธฐ์๋ ๋ค์ ์๊ธฐ์์กฐ์ด์ง๋ง, ๊ฒฝ๋ก ์์ค์ด ์ฑ์ ๋ํ ์ฌ๋ฐ๋ฅธ ์ ๊ทผ ๋ฐฉ์์ด๋ผ๋ฉด Apollo + GraphQL๋ ์์ธ๋ ์๋์ด์ผ ํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก ๋ชจ๋ ๋ฐ์ดํฐ ์ข
์์ฑ๊ณผ ๋น๋๊ธฐ ์์
์ด ๊ตฌ์ฑ ์์์์ ๋ถ๋ฆฌ๋์ด ์์ผ๋ฉด ํ
์คํธ๊ฐ ํจ์ฌ ์ฌ์์ง๋๋ค. ๊ด์ฌ์ฌ ๋ถ๋ฆฌ๋ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ๋ํด ๊ฑฑ์ ํ ํ์ ์์ด ๊ตฌ์ฑ ์์๋ฅผ ํ
์คํธํ ์ ์์ ๋ ์ฃผ์ ์์ฐ์ฑ ํฅ์ ํจ๊ณผ์
๋๋ค. ๋ฌผ๋ก ํ
์คํธ์์ ๋ฏธ๋ฆฌ ๋น๋๊ธฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ์ํํ์ฌ ์ ์ฅ์๋ฅผ ์ฑ์์ผ ํ์ง๋ง ๊ตฌ์ฑ ์์์์ ๋ถ๋ฆฌํ๋ฉด ๋ชจ๋ ํ
์คํธ์์ ์ฌ์ ์์
์ ์ฌ์ฉํ๋ ์ผ๋ถ setup
๋์ฐ๋ฏธ ํจ์์์ ์ด๋ฌํ ์์
์ ์ฝ๊ฒ ํ์ํํ ์ ์์ต๋๋ค. ๊ตฌ์ฑ ์์๊ฐ ๋ ๋๋ง๋๋ ๋ฐฉ์์ ํ
์คํธํ๊ธฐ ์ ์ ์ ์ฅ์๋ฅผ ์ฑ์ฐ์ธ์. :)
@faceyspacey ์ ์ ์ผ๋ก ๋์ํฉ๋๋ค. ๊ทธ๋ฌ๋ Apollo๋ GraphQL์ ์ฌ์ฉํด ๋ณธ ์ ์ด ์์์ ์ธ์ ํด์ผ ํฉ๋๋ค. ํ์คํ ํ์ธํ๊ณ ์ฌ์ฉ ์ฌ๋ก์ ์ด๋ป๊ฒ ๋ง๋์ง ํ์ธํ ๊ฒ์ ๋๋ค.
์ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ปจํธ๋กค๋ฌ์ ๋ํ ๋ชจ๋ ๋ฐ์ดํฐ์ ์ข ์์ฑ์ ๊ฐ์ ธ์ค๋ MVC ํจํด์ ์ฌ์ฉํ์ฌ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ฑํ๋ ๋ฐ ๋งค์ฐ ์ต์ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ทฐ ๋๋ ๋น์ฆ๋์ค ๋ก์ง์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ์ ํฉ๋๋ค. ๋น์ ์ด ๋งํ๋ฏ์ด ๋ณด๊ธฐ๊ฐ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ์ฐ๊ฒฐ๋์ง ์๊ธฐ ๋๋ฌธ์ ํ ์คํธ๊ฐ ํจ์ฌ ์ฌ์์ง๋๋ค.
View ๋ถ๋ถ์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๋ MVC ์์ฉ ํ๋ก๊ทธ๋จ์ ๋ณด์๋๋ฐ ๋์ฐํฉ๋๋ค. ๋ ๋ค ์ผ๋ถ ๋ณด๊ธฐ/๊ตฌ์ฑ ์์์ ์จ๊ฒจ์ ธ ์๊ณ ํ ์คํธ๊ฐ ๋ ์ด๋ ค์์ง๊ฑฐ๋ ๋ถ๊ฐ๋ฅํด์ง๊ธฐ ๋๋ฌธ์ ๊ฐ์ ธ์ฌ ๋ฐ์ดํฐ๊ฐ ๋ฌด์์ธ์ง ์ ํ ๋ชจ๋ฆ ๋๋ค.
์ ์๊ฒ Redux-First Router๋ MVC์ ์ปจํธ๋กค๋ฌ ๋ถ๋ถ๊ณผ ๋งค์ฐ ํก์ฌํฉ๋๋ค. ์ด๊ฒ์ ๋งค์ฐ ์๋ฏธ๊ฐ ์์ต๋๋ค :)
๊ฐ์ฌํฉ๋๋ค.
ํ๋ฃจ๊ฐ ๋๋๋ฉด ์๋ก์ด ์คํ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋จ: ๋ฆฌ๋์ค
V: ๋ฐ์
C: Redux-First ๋ผ์ฐํฐ(๊ณง "Rudy" ๋ก ์ด๋ฆ ๋ณ๊ฒฝ ์์ )
React(ํนํ Redux)๊ฐ ๋์์ ๋ ์ฐ๋ฆฌ ๋ชจ๋๋ MVC์ ๊ณ ๋ ์งํ๋ฅผ ๋ฒ๋ฆฌ๊ณ ์ถ์ดํ๋ ๊ฒ์ฒ๋ผ ๋ณด์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ถ๊ทน์ ์ผ๋ก ๋จ์ํ ์ด๋ฅผ ์ง์ํ๊ธฐ ์ํ ๋๊ตฌ๊ฐ ์์ง ๊ตฌ์ถ๋์ง ์์ ๊ฒ ์ด์์ ์๋๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๊ฒฐ๊ตญ ์ฐ๋ฆฌ๋ ๋ฐ์์ ์ธ ํด๋ผ์ด์ธํธ ์ฐ์ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ์ฌ์ ํ MVC์ ์ด์ ์ ํฌ๊ฒ ๋๋ฆฌ๊ณ ์์ต๋๋ค.
์๋ก์ด ํด๋ผ์ด์ธํธ ์ฐ์ ์คํ๊ณผ ๊ธฐ์กด ์๋ฒ ์ธก MVC์์ ์ฝ๊ฐ ๋ค๋ฅด๊ฒ ์๋ํ ์ ์์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ๋์ผํ 3 ๋ถ๋ฆฌ๋ ๊ด์ฌ์ฌ์ ๋๋ค.
3 ๊ฐ์ ์ํธ ์์ฉ/๋์์ ์ฐจ์ด์ ์ด ๋ฌด์์ธ์ง์ ๊ดํด์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ณผ๊ฑฐ์๋ ์ปจํธ๋กค๋ฌ๊ฐ ์ด๊ธฐ ๋จ๊ณ์์ ๋ชจ๋ธ์ ์ป์ ๋ค์ ๋ทฐ๋ฅผ ๋ ๋๋งํ๋ค๋ ๊ฒ์ ๋๋ค. ์ด์ ์ปจํธ๋กค๋ฌ(RFR)๊ฐ ๋ทฐ๋ฅผ ์ฆ์ ๋ ๋๋งํ๊ณ ("UI ๋ชจ๋ธ", ์ฆ Redux ์ํ๋ฅผ ํตํด ์ ํ๋จ) ์ปจํธ๋กค๋ฌ๊ฐ ๋๋ฉ์ธ ๋ชจ๋ธ (Redux ์ํ์๋ ์ ์ฅ๋จ)์ ์ฐพ์ผ๋ฉด ๋ทฐ๋ฅผ ๋ ๋ฒ์งธ ๋ก
์๋ ํ์ธ์ ์ฌ๋ฌ๋ถ, ์ด ๋งํฌ๋ฅผ ๋ณด์ญ์์ค. ๋ค์์ ๋ฐ์ดํฐ ์๋ฒ ์ธก ๋ ๋๋ง ์์ ๋๋ค. https://github.com/bananaoomarang/isomorphic-redux
@harut55555 idk
๋ณ๊ฒฝ ์ฌํญ์ด ์์ต๋๊น? ๋ฆด๋ฆฌ์ค 16 ๋ฐ์ ๋ฐ ๋๋ถ๋ถ์ ์๋ฃจ์ ์ด ์๋ํ์ง ์์
ํ์ฌ ์ ๊ทผ ๋ฐฉ์์ redux observable ๋๋ redux thunk์ ๊ฐ์ ๋๊ตฌ์ ํจ๊ป redux๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋์ ์ฌ์ฉ ์ฌ๋ก
<App>
<Page>
<AsyncModule hre="different.com/Button.react.js" /> downloaded from external url on server or client
</Page>
</App>
๋ฌธ์ ๋ ์ฑ์ ๋ ๋๋งํ๊ธฐ ์ ์ ๋ด๊ฐ ๊ฐ์ง ๊ตฌ์ฑ ์์์ ์ข ๋ฅ๋ฅผ ๋ชจ๋ฅธ๋ค๋ ๊ฒ์ ๋๋ค.
๋จ์ง ๊ถ๊ธํ ๊ตฌ์ฑ ์์ ๋์ ๋ฐ์ดํฐ/์ปจํ ์ธ ๋ฅผ ๋ค์ด๋ก๋ํ์ง ์๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
์ธ์ ? ๋์ ํ์ด์ง๊ฐ ์๊ณ ๊ตฌ์ฑ ์์๊ฐ ์์ ์๋ ์๊ณ ์์ ์๋ ์์ต๋๋ค.
์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ์ํ๋ ๊ฒ ๊ฐ์ต๋๋ค https://reactjs.org/docs/conditional-rendering.html
๋ผ์ฐํ ๋ฌธ์ ๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ฐ์์ ๋ ๋๋ง ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ณ ์์ฒญํ์ง ์๊ณ ํ์ด์ง๋ฅผ ๋ ๋๋งํด์ผ ํฉ๋๋ค.
Apollo์ @graphql
๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ ๋ก๋๊ฐ ๋งค์ฐ ๊ฐ๋จํด์ง๊ณ React-Router v4 ๊ตฌ์ฑ ์์ ๊ธฐ๋ฐ API๋ ๊ตฌ์ฑ ๊ฐ๋ฅํ ๋ผ์ฐํ
์ ๊ฐ๋จํ๊ฒ ๋ง๋ญ๋๋ค. ๋ ๋ค Redux์ ์ ํ๋ฆฌ์ผ์ด์
์ํ์ ์ง๊ตํฉ๋๋ค.
๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋จ์ผ ํจ์ค ์คํธ๋ฆฌ๋ฐ ๋ ๋๋ง์ ์ํํ๋ ค๋ฉด render()
๊ฐ ์ฝ์์ ๋ฐํํ ์ ์์ด์ผ ํฉ๋๋ค(ํด๋ผ์ด์ธํธ์์๋ ์ง๊ธ์ฒ๋ผ, ์๋ฒ์์๋ ์ฝ์๋ง ๋ฐํ).
๊ทธ๋ฌ๋ฉด @graphql
๋ ๋ฐ์ดํฐ๊ฐ ๋ก๋๋ ํ render()์ ๋ํ ์ฝ์์ ๊ฐ๋จํ ๋ฐํํ ์ ์์ต๋๋ค. ๋๋จธ์ง๋ ๋ชจ๋ ํ๋ฒํ React์
๋๋ค.
๋ช ๋ฌ ์ ๋๋ JSConf ์์ด์ฌ๋๋์์ React์ ๋ค๊ฐ์ค๋ ๋น๋๊ธฐ ๋ ๋๋ง ๊ธฐ๋ฅ์ ์ค๋ช ํ๋ ์ฐ์ค์ ํ์ต๋๋ค(๋ ๋ฒ์งธ ๋ถ๋ถ ์ฐธ์กฐ): https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react -16.html. ์ด๊ฒ์ ํด๋ผ์ด์ธํธ ์ธก ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ๊ดํ ๊ฒ์ ๋๋ค.
์ด์ @acdlite ๋ React ๊ตฌ์ฑ ์์์์ ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์์ผ๋ก ๋๊ธฐํ๊ณ ์ค๋น๊ฐ ๋๋ฉด ๋งํฌ์ ์ ์ ์ง์ ์ผ๋ก ํ๋ฌ์ํ๋ ๋ฐ ๋์ผํ ๊ฐ๋ ์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ค๋ช ํ์ต๋๋ค. https://www.youtube.com/watch?v= z-6JC0_cOns
์ด ๊ฐ์ฐ์ ์ฆ๊ฒ๊ฒ ์์ฒญํ์๊ธฐ ๋ฐ๋๋๋ค! 1๋ ์ ๋ ์ง๋๋ฉด ์ด ๋ฌธ์ ๋ฅผ ๋ง๋ฌด๋ฆฌํ๊ณ ์ด์ ๋ํ ๊ณต์ ์ ๋ต์ ์ธ์ธ ์ ์์ ๊ฒ์ ๋๋ค.
๋ง์ด ์๊ฐ๋๋ค์. ์ฐ๋ฆฌ๋ ๋ฏธ๋๋ฅผ ํจ๊ป ๊ณํํ๋ฉฐ ๊ฒฐํผํฉ๋๋ค. ์ด์ ๊ทธ๋งํ๊ณ ์ ๋ฅผ ๋ง๋๋ฌ ์ค์ธ์. ์๊ฐ์ ํญ์ ์ฌ๋
ReactDOMServer.renderToStaticMarkup
๋ฅผ ์ฌ์ฉํ์ฌ ํธ๋ฆฌ๋ฅผ ํ์ํ๊ณ , ๋น๋๊ธฐ ์ข
์์ฑ์ ๋๋ฌํ๋ ์์น์ ์ฑ
๊ฐํผ๋ฅผ ๋ฐฐ์นํ๊ณ (์ผ๋ฐ์ ์ผ๋ก API์์ ๋ฐ์ดํฐ ๋ก๋), ์ ์ฒด ํธ๋ฆฌ๊ฐ ํด๊ฒฐ๋ ๋๊น์ง ์ด๋ฌํ ์ข
์์ฑ์ด ํด๊ฒฐ๋ ๋ ํธ๋ฆฌ๋ฅผ ๊ณ์ ํ์ํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ต์ข
ReactDOMServer.renderToString
๋ฅผ ์ํํ์ฌ ์ค์ ๋ก HTML๋ก ๋ ๋๋งํฉ๋๋ค. ์ด์ ๋ชจ๋ ์ข
์์ฑ์ด ํด๊ฒฐ๋์๊ธฐ ๋๋ฌธ์ ๋๊ธฐํ๋ฉ๋๋ค.
react-baconjs
: render-to-html.js ์์ ์ด ์ ๊ทผ ๋ฐฉ์์ ์ทจํ์ต๋๋ค. ์ด๋ฌํ ์ ๊ทผ ๋ฐฉ์์ ๊ถ์ฅํ๋ ๋ค๋ฅธ ๋ฌธ์ ์์ @gaearon์ด ์์ฑํ ๋๊ธ์์ ์๊ฐ์ ๋ฐ์์ต๋๋ค.
@steve-tailor ์, ์๋ํฉ๋๋ค. ์ด๊ฒ์ ๋ํ ๋ชจ๋ React ์ฑ์์ ์๋ํ๋ ๋ณด๋ค ์ผ๋ฐ์ ์ธ ๋ชฉ์ ์ ์๋ฃจ์ ์ธ react-frontload ์์ ์ฌ์ฉํ๋ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋๋ค.
๋ณธ์ง์ ์ผ๋ก ๋งํ๋ฏ์ด ๋๊ธฐ ๋ ๋๋ง ๋ ผ๋ฆฌ๋ฅผ ๋ ๋ฒ ์คํํ๊ณ ์ฒซ ๋ฒ์งธ ๋ ๋๋ง์์ ์ ์คํ ๋ชจ๋ ๋ฐ์ดํฐ ๋ก๋ ์ฝ์์ด ๋ ๋ฒ์งธ๋ฅผ ์คํํ๊ธฐ ์ ์ ํด๊ฒฐ๋ ๋๊น์ง ๋๊ธฐํ์ฌ ๋น๋๊ธฐ ๋ ๋๋ง์ ๊ฐ์ฅํ๋ ๊ฒ์ ๋๋ค.
๋ถ๋ช ํ ์ฝ๊ฐ์ ๋ญ๋น๊ฐ ์์์๋ ๋ถ๊ตฌํ๊ณ ์ถฉ๋ถํ ์ ์๋ํฉ๋๋ค(์ฒซ ๋ฒ์งธ ๋ ๋์ ์ถ๋ ฅ์ ๋จ์ง ์ฝ์ ๊ทธ ์ด์์ด๋ฉฐ, ๊ทธ๋ฅ ๋ฒ๋ ค์ง๋ ์ค์ HTML์ด๊ธฐ๋ ํฉ๋๋ค). ์ง์ ํ ๋น๋๊ธฐ ์๋ฒ ๋ ๋๋ง์ด React๋ก ๋ง๋ค์ด์ง๋ฉด ๋๋์ต๋๋ค.
@davnicwil ์ํ์ด! ํน์ ๋น๋๊ธฐ SSR ์๋ฃจ์ ์ ์ผ๋ฐํํ๋ ๊ฒ์ ๋ํด ์๊ฐํ์ต๋๋ค. react-frontload๊ฐ ๋ฌด์ ํ ๋น๋๊ธฐ ๊น์ด๋ฅผ ์ฒ๋ฆฌํฉ๋๊น? "๋ ๋ฒ"์ด๋ผ๊ณ ๋งํ๊ธฐ ๋๋ฌธ์ ๋ฌป๋ ๊ฒ์ ๋๋ค.
@steve-tailor ๊ฑด๋ฐฐ! ์, ๊น์ด๊ฐ ํธ๋ฆฌ์ ๊ตฌ์ฑ ์์ ๊น์ด๋ฅผ ์๋ฏธํ๋ค๋ฉด ๋ฌด์ ํ์ ๋๋ค. ์ด๋ฅผ ํตํด ์ปดํฌ๋ํธ ์์ฒด(๊ณ ์ฐจ ์ปดํฌ๋ํธ ํฌํจ)์์ ๋ฐ์ดํฐ ๋ก๋ ํจ์๋ฅผ ์ ์ธํ ์ ์์ผ๋ฉฐ ์ฒซ ๋ฒ์งธ ๋ ๋๋ง์์ ํด๋น ํจ์๊ฐ ๋ฐ์ํ๋ฉด ์คํ๋๊ณ ์ฝ์์ด ์์ง๋ฉ๋๋ค.
์๋ํ์ง ์๋ ๊ฒ์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์์ผ๋ก ๋ก๋ํ๋ ์ถ๊ฐ ํ์ ๊ตฌ์ฑ ์์๊ฐ ์๋ ๊ฒฝ์ฐ์ ๋๋ค. ์ด ๊ตฌ์ฑ ์์๋ ํ๋นํ ๊ฒฝ์ฐ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ๋์ ์ผ๋ก ๋ ๋๋ง๋ฉ๋๋ค. ๊ทธ๊ฒ์ ๋จ์ง ์ฑ์ด ์ด๋ฐ ์ข ๋ฅ์ ์ค์ฒฉ์ด ์๋๋ก ๊ตฌ์กฐํ๋์ด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ค์ ๋ก ์ ๊ฐ ๋ฐ๊ฒฌํ ์ด๊ฒ์ ์์ฒญ๋ ์ ํ์ด ์๋๋๋ค. ์ฌ์ค ์ค์ฒฉ๋ ๋น๋๊ธฐ ๋ ผ๋ฆฌ๋ ์ง๋ ฌ ์์ฒญ๊ณผ ๋ ๊ธด ๋๊ธฐ ์๊ฐ์ ์๋ฏธํ๋ ๋ฐ๋ฉด ํ๋ฉดํ๋ ๋ณ๋ ฌ ์์ฒญ์ ์๋ฏธํ๊ธฐ ๋๋ฌธ์ ์ฌ๋ฌ ๋ฉด์์ UX ์ธก๋ฉด์์ ๋ ์ข์ต๋๋ค .
์ฆ, ์ค์ฒฉ ๋ฌธ์ (์ค์ ๋ก ์ด ์ ์ฒด ๋น๋๊ธฐ ์๋ฒ ๋ ๋๋ง ๋ฌธ์ )๋ ๊ฐ๊น์ด ์ฅ๋์ React์ ํฌํจ๋ Suspense ํญ๋ชฉ์ผ๋ก ํด๊ฒฐ๋ ์ ์์ต๋๋ค. ๐ค
์ฐธ๊ณ ๋ก ์ด ์์ ์ ์์ํ์ต๋๋ค.
https://reactjs.org/blog/2018/11/27/react-16-roadmap.html#suspense -for-server-rendering
๋ฉ์ง๋ค @gaearon!
@davnicwil react-baconjs
์ ๋ฌด์ ํ ๊น์ด๋ฅผ ์ง์ํฉ๋๋ค.
@gaearon ๋๋ ์ด๊ฒ์ด ๊ด์ฐฐ ๊ฐ๋ฅํ ๋ฐ์ฌ JSX๋ฅผ ๋ฐ์ ๊ตฌ์ฑ ์์๋ก ๋ณํํ ์ ์๋๋ก ์์ฑ ๊ตฌ๋ ์์ ๊ด์ฐฐ ๊ฐ๋ฅํ ์ง์์ ๊ฐ๋ฅํ๊ฒ ํ๋์ง ๊ถ๊ธํฉ๋๋ค.
์ด ๊ธฐ๋ฅ์ ๊ฐ๊ณ ์ถ์ ์ด์ ๋ ๋ ๊ฐ์ง์ ๋๋ค. ๋จผ์ ๋ด ์ฑ์์ ์ํ๋ ์น ์์ ์์ ์ ์ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ ๊ตฌ์ฑ ์์๊ฐ ์๊ตฌํ๋ ํด๋น ์ํ์ ๋นํธ๋ฅผ ๊ฒ์ํ๋ ๊ฒ์ ๋น๋๊ธฐ ์์ ์ด์ง๋ง 5ms ์ ๋ ๊ฑธ๋ฆฌ๋ฉฐ React๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ์๋ฌด ๊ฒ๋ ๋ ๋๋งํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. ๋์งธ, ์ง๊ธ ๋น์ฅ์ ์ต์ ๋ฒ๋ธ์ ์ปดํฌ๋ํธ๋ก ๋ณํํ๋ ๋ณดํธ์ ์ธ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์ต์ ๋ฒ๋ธ์ด ์ฒซ ๋ฒ์งธ ๊ฐ์ ๋๊ธฐ์ ์ผ๋ก ๋ฐฉ์ถํ๋ฉด ๊ทธ ๊ฐ์ ์ป๊ธฐ ์ํด ๊ตฌ๋ ํ๊ณ , ๊ตฌ๋ ์ ์ทจ์ํ๊ณ , ๋ณ๊ฒฝ ์ฌํญ์ ์์ ํ๊ธฐ ์ํด ๋ค์ ๊ตฌ๋ ํฉ๋๋ค(์ฆ, Replay create-observable ๋ฌธ์์ ์ฃผ์ ์). ๊ทธ๋ฆฌ๊ณ ๋น๋๊ธฐ์์ผ๋ก ์ฒซ ๋ฒ์งธ ๊ฐ์ ๋ด๋ณด๋ด๋ ๊ฒฝ์ฐ ์ฒ์์๋ null์ ๋ ๋๋งํ๊ณ ๋ณ๊ฒฝ ์ฌํญ์ ์์ ๋๊ธฐํฉ๋๋ค.
@steve-taylor react-frontload๋ ์ด์ 1.0.7
๋ฆด๋ฆฌ์ค์ ํจ๊ป ๊ตฌ์ฑ ์์ ์ค์ฒฉ์ ๋ฌด์ ํ ๊น์ด๋ ์ง์ํฉ๋๋ค.
์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ด ์ค๋ ๋๋ฅผ ์์ํ๋ ์ผ๋ถ ์ฌ๋๋ค์๊ฒ ์ ์ฉํ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ์ต์ํ์ ํตํฉ ๋ ธ๋ ฅ์ผ๋ก ํด๋ผ์ด์ธํธ/์๋ฒ ๋ ๋์์ ์๋ํ๋ ๋น๋๊ธฐ ๋ฐ์ดํฐ ๋ก๋ฉ ์๋ฃจ์ ์ ์ฐพ๊ณ ์๋ค๋ฉด ํ์ธํด์ผ ํฉ๋๋ค.
์ฐ๋ฆฌ๋ ์ฑ์ด React Hooks๋ก ๋น๋๋ ๋ ์ด ๋ฌธ์ ๋ฅผ ๊ฒช์๊ณ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด
๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๋ ์ฌ์ ํ ๊ณต์ ์๋ฃจ์ ์ ๊ธฐ๋ํ๊ณ ์์ต๋๋ค. react-frontload์์ ๋งํ๋ฏ์ด ํ์ฌ ๋ ๋๋ง์ด ์์๋๋ฉด ๋น๋๊ธฐ ๋ฐ์ดํฐ ๋ก๋๊ฐ ๋ฐ์ํ ๋๊น์ง ๊ธฐ๋ค๋ฆด ์ ์๋ ๊ธฐ๋ณธ ์ ๊ณต ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋ช ๋ฌ ์ ๋๋ JSConf ์์ด์ฌ๋๋์์ React์ ๋ค๊ฐ์ค๋ ๋น๋๊ธฐ ๋ ๋๋ง ๊ธฐ๋ฅ์ ์ค๋ช ํ๋ ์ฐ์ค์ ํ์ต๋๋ค(๋ ๋ฒ์งธ ๋ถ๋ถ ์ฐธ์กฐ): https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react -16.html. ์ด๊ฒ์ ํด๋ผ์ด์ธํธ ์ธก ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ์ ๊ดํ ๊ฒ์ ๋๋ค.
์ด์ @acdlite ๋ React ๊ตฌ์ฑ ์์์์ ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์์ผ๋ก ๋๊ธฐํ๊ณ ์ค๋น๊ฐ ๋๋ฉด ๋งํฌ์ ์ ์ ์ง์ ์ผ๋ก ํ๋ฌ์ํ๋ ๋ฐ ๋์ผํ ๊ฐ๋ ์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ค๋ช ํ์ต๋๋ค. https://www.youtube.com/watch?v= z-6JC0_cOns
์ด ๊ฐ์ฐ์ ์ฆ๊ฒ๊ฒ ์์ฒญํ์๊ธฐ ๋ฐ๋๋๋ค! 1๋ ์ ๋ ์ง๋๋ฉด ์ด ๋ฌธ์ ๋ฅผ ๋ง๋ฌด๋ฆฌํ๊ณ ์ด์ ๋ํ ๊ณต์ ์ ๋ต์ ์ธ์ธ ์ ์์ ๊ฒ์ ๋๋ค.