์ด ๊ธ์ udemy์ Next.js & React - ์๋ฒฝ ์ ๋ณต ๊ฐ์ด๋ (incl. Two Paths) ๊ฐ์ข๋ฅผ ๋ฐํ์ผ๋ก ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
86. ๋ชจ๋ ๊ฐ์
Next.js๋ฅผ ์ด์ฉํ๋ฉด ํ์คํ React ์ฑ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. Next.js๋ ์๋ฒ ์ฌ์ด๋์์ ํ์ด์ง๋ฅผ ์ฌ์ ๋ ๋๋ง ํด์ค๋๋ค. Next.js๋ ์ฝ๋ ์คํ์ ์์ด์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ฟ๋ง ์๋๋ผ React ์ฑ์ด ์คํ๋๋ ์ฌ์ฉ์์ ๋ธ๋ผ์ฐ์ ๋ฟ๋ง ์๋๋ผ ์๋ฒ ์ฌ์ด๋์์ ์ฝ๋๋ฅผ ์คํํ ๋๋ ๋์์ ์ค๋๋ค. ํ์ด์ง์ ํ์๋์ด์ผ ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ค๋นํ๊ฑฐ๋ ๋ก๋ฉํ๋ ์์ ์ ๋๋๋ค๋ ์๋ฏธ์ ๋๋ค.
- ๋ฐ์ดํฐ fetching์ด ๋ฌด์์ธ๊ฐ
- Static VS Server-side Page
- ์ด๋ป๊ฒ ๋ฐ์ดํฐ fetch ํ๋๊ฐ
์ด ์๋ฏธ์ ๋ํด ์์ธํ ์ดํด๋ณด๋๋ก ํฉ์๋ค.
87. ๊ธฐ์กด React App (๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ fetching)์ ๋ฌธ์ ์
์ฌ์ฉ์๋ค์ ๋ฐ์ดํฐ๊ฐ ์ค์ง์ ์ผ๋ก ํ์ด์ง์ ๋ก๋ฉ๋๊ธฐ๊น์ง๋ฅผ ๊ธฐ๋ค๋ ค์ผ ํฉ๋๋ค. ํ์ง๋ง ๋ฐฑ์๋ API๋ฅผ ์ด์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ํ์นญํ๋ ์ค์ ํ์ด์ง์์๋ ๋ฐ์ดํฐ ๋ก๋ฉ์ ๋ช ์ด๊ฐ ์์๋ ์ ์์ด ์ง์ฐ์ด ๋ฐ์ํฉ๋๋ค. ์ฌ์ฉ์ ๊ฒฝํ์ ์ต์ ํ๊ฐ ์๋๋๋ค. ๋ ํฐ ๋ฌธ์ ๋ ๊ฒ์ ์์ง ์ต์ ํ์ ์์ต๋๋ค. HTML ์ฝ๋๋ ์๋ฒ์์ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐ์ดํฐ๊ฐ ๋ค์ ์ ์ก๋๋ฉด์ ๊ฒ์ ์์ง์ ์ด์ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ด ๋๋ค. ์ฝ์ฒธ์ธ ๊ฐ ์ ํ ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ง์ ๋๋ค.
๋ฐ๋ผ์ ์ฝํ ์ธ ๊ฐ ์ค์ํ๋ฉฐ ๊ฒ์ ์์ง์ด ํด๋น ์ฝํ ์ธ ๋ฅผ ์ด๋ํ๊ณ ๋ ์ธ๋ฑ์ฑ ํ๊ฒ ํ๋ ค๋ฉด ์ฌ์ ์ก ๋ฐฉ์์ ์ ํฉํ์ง ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ์ ํด์ผ ํ๋ ์น์ฑ์ด๊ฑฐ๋, React๋ก ๊ตฌ์ถ๋ ๊ด๋ฆฌ์ ๋์๋ณด๋๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ๊ฒ์ ์์ง์ด ์๊ด์์ ์๋ ์์ต๋๋ค. ํ์ง๋ง ๋ธ๋ก๊ทธ์ ์ผํ๋ชฐ์ฒ๋ผ ๋ง์ ์ฝํ ์ธ ๊ฐ ์๋ ์ฑ์ ๊ฒฝ์ฐ ๊ฒ์ ์์ง์ ๋ ธ์ถ๋๊ธธ ๋ฐ๋ ํ ๋ฐ ์ด๋ฐ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ๋ฅผ ์ฌ์ ์ก ํ๋ค๋ ๊ฒ์ ๋ฐ๋์งํ์ง ์์ต๋๋ค.
ํ์ค React๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ํ ์ ์๋ ์ค๋ฅ๋ก, ๋ฐ์ดํฐ๋ฅผ fetching ํ๋ ์ผ์ด ์ปดํฌ๋ํธ๊ฐ ๋ก๋ฉ๋ ํ์ฌ์ผ ํ๋ค๋ ๋ป์ ๋๋ค. ์ฆ ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์ ๋ฐ์ดํฐ๋ฅผ fetching ํ๊ณ ํ๋ฉด์ ๋ ๋๋ง๋ ํ์ ์๋ฒ๋ก ์์ฒญ์ ๋ณด๋ผ ์ ์์ต๋๋ค. ์ด ์ ์ Next.js์ ์๋ฒ ์ฌ์ด๋ ๊ธฐ๋ฅ๊ณผ ๋ด์ฅ ๊ธฐ๋ฅ์ ํตํด ํด๊ฒฐํ ์ ์์ต๋๋ค.
88. NextJS๊ฐ ํ์ด์ง๋ฅผ ์ค๋นํ๊ณ , ์ฌ์ ๋ ๋๋ง์ ํ๋ ๋ฐฉ์
์ด๋ค ํ์ด์ง๊ฐ ์๋ค๊ณ ํด๋ด ์๋ค. pages ํด๋์์ ํ์ด์ง ํ์ผ์ ๋ก๋ฉํ๋ some-route ํ์ด์ง๋ ๋ฐ์ดํฐ๋ฅผ ํ์๋ก ํฉ๋๋ค. ์ด ๋ผ์ฐํธ์ ์์ฒญ์ด ์ ์ก๋ ๊ฒฝ์ฐ ์ฆ ์ฌ์ฉ์๊ฐ ํด๋น ํ์ด์ง๋ฅผ ๋ฐฉ๋ฌธํ๋ฉด Next.js๊ฐ ์ฌ์ ๋ ๋๋ง๋ ํ์ด์ง๋ฅผ ๋ฐํํฉ๋๋ค. ์ด๊ฒ์ด ํ์ค React์์ ์ฐจ์ด์ ์ ๋๋ค. ํ์ค React๋ผ๋ฉด ๋น HTML ํ์ผ๊ณผ ๋ชจ๋ JS ์ฝ๋๊ฐ ํ์๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ JS ์ฝ๋๊ฐ ์คํ๋๋ฉด ์คํฌ๋ฆฐ์ ๋ด์ฉ์ด ํ์๋ฉ๋๋ค. ๊ทธ ์๋๊ฐ ๋นจ๋ผ์ ์ฌ์ฉ์์๊ฒ ๋ฌธ์ ๋ก ๋ณด์ด์ง ์์ ์ ์์ง๋ง, ์ผ๋ฐ DOM ๊ตฌ์กฐ ์ธ์ ํ์ํ ๋ฐ์ดํฐ๊ฐ ์๋ฒ๋ก๋ถํฐ ๋ก๋ฉ๋ ๋์๋ ์๊ฐ์ด ์์๋ ์ ์์ต๋๋ค. ์ฌ์ ๋ ๋๋ง ๋์ง ์์์ ๋ ๋ง์ ๋๋ค.
์ด ์์ ์ Nextj๊ฐ ํ๋๋ฐ, ํ์ด์ง๋ฅผ ๋ค์ ํด๋ผ์ด์ธํธ๋ก ์ ์ก๋ ๋ค์๋ง ๋ฐ์ดํฐ๋ฅผ ๋ก๋ฉํ๋ ๋์ ํ์ด์ง์ ํ์ํ ๋ฒํ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์๋ HTML ์ฝํ ์ธ ๋ฅผ ์ฌ์ ์ ๋ ๋๋ง ํฉ๋๋ค. ์ฌ์ ์ HTML ํ์ผ์ ์์ฑํด๋๊ณ , ์์ ํ ์ฑ์์ง HTML ํ์ผ์ ํด๋ผ์ด์ธํธ, ์ฆ ํ์ด์ง์ ๋ฐฉ๋ฌธ์์๊ฒ ์ ์กํฉ๋๋ค. SEO ๊ด์ ์์ ๋งค์ฐ ํ๋ฅญํฉ๋๋ค. ํ์ง๋ง ์ฌ์ ํ Interactive React ์ฑ์ ํ์ํฉ๋๋ค. interactive ์ฑ์ ๋ง๋ค๋ ค๊ณ React๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์๋๋ผ๋ฉด HTML์ด๋ Css ์ฑ์ ๊ตฌ์ถํ ๊ฒ์ ๋๋ค. React๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ํฌ๋ผ ์ ์์ด๋ ์๋ฌ ๊ฒ์ฆ ๋ฑ์ ๋ฒํผ ํด๋ฆญ์ ๋ฐ์ํด์ ์ฌ์ฉ์ ์ํธ์์ฉ์ ํ๊ธฐ ์ํจ์ ๋๋ค.
Next.js๋ ๋จ์ํ ์ฌ์ ๋ ๋๋ง๋ ํ์ด์ง๋ฅผ ์ฌ์ ์กํ๋ ๋ฐ ๊ทธ์น์ง ์๊ณ , ํฌํจ๋ JS ์ฝ๋๋ฅผ ๋ชจ๋ ์ฌ์ ์กํฉ๋๋ค. ์ด๋ฐ ์ฌ์ ์ก์ ํด๋น ํ์ด์ง์ ๋ํด Hydrate ํ๋ค๊ณ ํฉ๋๋ค. ์ฌ์ ์ก๋ JS ์ฝ๋๋ ๋์ค์ ์ฌ์ ๋ ๋๋ง ๋ ํ์ด์ง๋ฅผ ๋์ฒดํ๊ณ ์ด์ React๊ฐ ์๋ง๋ ์์ ์ ์ํํฉ๋๋ค. ์ฒ์ ์ฌ์ ์กํ ์ฌ์ ๋ ๋๋ง๋ ํ์ด์ง์๋ ์ฃผ์ ์ฝํ ์ธ ๊ฐ ๋ชจ๋ ํฌํจ๋์ด ์๋ ์ํ์ด๊ธฐ ๋๋ฌธ์ ์ด์ ๊ฒ์ ์์ง ํฌ๋กค๋ฌ๋ ์ ์ฒด ํ์ด์ง์ ์ด๋ฏธ ํฌํจ๋ ๋ชจ๋ ์ฝํ ์ธ ๋ฅผ ์ดํด๋ณด๊ฒ ๋ฉ๋๋ค. ์ด๋ ์ํธ์์ฉ ํ์ด์ง๊ฐ ์๋์ด๋ ํฌ๋กค๋ฌ๋ ์ฝํ ์ธ ๋ง ํ์ธํ๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ต๋๋ค. ์ด๊ฒ ์ฌ์ ๋ ๋๋ง์ ๊ฐ๋ ์ ๋๋ค. ๋ ์ ํํ ๋งํ๋ฉด Next.js๋ ํ์ด์ง๋ฅผ ์ฌ์ ์ ์ค๋นํ๋๋ฐ, ์ด๋ ๋ชจ๋ Html ์ฝํ ์ธ ๋ฅผ ์ฌ์ ์ ๊ตฌ์ถํ๊ณ ํ์ํ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ ์ ๋ก๋ฉํ๋ ๋ฐฉ์์ ๋ฐ๋ฆ ๋๋ค. ์ฌ์ ๋ ๋๋ง์ ์ค์ง ์ต์ด ๋ก๋ฉํ ๋๋ง ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
Next.js์ React๋ก ๊ตฌ์ถ๋ ํ์ด์ง์์๋ ํ์ด์ง์ Hydrate, ์ฆ ์ฒซ ๋ฒ์งธ ๋ ๋๋ง์ด ๋๋๊ณ ๋๋ฉด ๋ค์ ํ์ค ์ฑ๊ธ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ๋์๊ฐ๋๋ค. ์ด๋๋ถํฐ React๊ฐ ํ๋ก ํธ์๋์์ ๋ชจ๋ ์ฒ๋ฆฌ๋ฅผ ์ํํฉ๋๋ค. Next.js์๋ ๋ ๊ฐ์ง pre-Rendering ์์์ด ์์ต๋๋ค. Static Generation, Server-side Rendering ์ ๋๋ค. SSR๊ณผ ์ ์ ์์ฑ์ ๊ฐ์ฅ ํฐ ์ฐจ์ด๋ Static Generation์ ๋น๋๋๋ ๋์ ๋ชจ๋ ํ์ด์ง๊ฐ ์ฌ์ ์์ฑ๋๋ค๋ ๊ฒ์ ๋๋ค. ๋ฐ๋ผ์ prod์ฉ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๋ค๋ฉด ๋ฐฐํฌ ์ ์ ๋ชจ๋ ํ์ด์ง๊ฐ ์ค๋น๋๋ค๋ ๊ฒ์ ๋๋ค. Server-side Rendering(SSR)์ ๊ฒฝ์ฐ์๋ ๋ฐฐํฌ ํ ์์ฒญ์ด ์๋ฒ๊น์ง ์ค๋ ๋ฐ๋ก ๊ทธ๋ ๋ชจ๋ ํ์ด์ง๊ฐ ์์ฑ๋ฉ๋๋ค.
89. "getStaticProps"๋ฅผ ํตํ static generation
์ผ๋ฐ์ ์ผ๋ก ๊ถ์ฅ๋๋ ๊ฐ๋ ์ ๋๋ค. ๋น๋ํ๋ ๋์ ํ์ด์ง๋ฅผ pre-Rendering ํ๋ ๊ฒ์ ๋๋ค. pre-Rendering ์ด๋ผ๋ ๊ฒ์ ์ฝํ ์ธ ๋ฅผ ๊ตฌ์ฑํ๋ ๋ชจ๋ HTML ์ฝ๋์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ ์ ์ค๋น์์ผ ๋๋๋ค๋ ๋ป์ ๋๋ค. ๋ณดํต ์๋ฒ ์ฌ์ด๋์์๋ง ์คํ๋๋ ์ฝ๋๋ฅผ ๋น๋ ํ๋ก์ธ์ค ๋์ ์คํ๋๋๋ก ํ์ฉํ๋ ๊ฒ์ ๋๋ค. ๋น๋ ์๊ฐ์ ๋ฐฐํฌ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ๋๋ฅผ ๋งํฉ๋๋ค. ๋น๋ ์๊ฐ ์ค ํ์ด์ง๊ฐ ์ฌ์ ์ ๊ตฌ์ถ๋์๊ธฐ ๋๋ฌธ์ ๋ฐฐํฌ๋๊ณ ๋๋ฉด ๊ตฌ์ถ๋ ํ์ด์ง๋ ์๋ฒ๋ ์ฑ์ ์คํ์ํค๋ CDN์ ํตํด์ ์บ์๋ก ์ ์ฅ๋ฉ๋๋ค. ์ด์ ์ฌ์ ๊ตฌ์ถ๋ ํ์ด์ง๋ฅผ ํตํด์ ์ฆ์ ์ ๋ ฅ ์์ฒญ์ด ์คํ๋ ์ ์์ต๋๋ค.
ํ์ด์ง ์ปดํฌ๋ํธ์์ ๊ฐ์ ธ์ฌ ์ ์๋ ํน์ํ ๋น๋๊ธฐ ํจ์์ธ getStaticProps()๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ํ์ด์ง ์ปดํฌ๋ํธ์ ๋ด๋ถ์ ์์ด์ผ ํ๋ฉฐ, ๋ค๋ฅธ React ์ปดํฌ๋ํธ๊ฐ ์๋ pages ํด๋์ component ํ์ผ ๋ด๋ถ๊ฐ ๊ทธ ์์น์ฌ์ผ ํฉ๋๋ค.
export async function getStaticProps(context) {...}
์ด๋ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํ๋ ๋น๋๊ธฐ ํจ์๋ก ๊ทธ ์์ await ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. getStaticProps ๋ด์ ์์ฑํ ์ฝ๋๋ ํด๋ผ์ด์ธํธ์๊ฒ ์ฌ์ ์ก๋๋ ์ฝ๋๋ก ํฌํจ๋์ง ์์ต๋๋ค. ์ฆ ํด๋น ํจ์ ๋ด์ ํฌํจํ๋ ์ฝ๋๋ ํด๋ผ์ด์ธํธ๋ ๋ณผ ์ ์์ต๋๋ค. (ex. db credential์ ํฌํจํ๊ณ ์๋ ๊ฒฝ์ฐ)
90. NextJS๋ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ ๋ ๋๋ง
์์ค๋ฅผ ๋ณด๋ฉด Next.js๊ฐ ์์ฑํ ์ด ํ์ด์ง์ ์์ค๋ ์ด์ ํ์ค React ์ฑ์์ ๋ดค๋ ๊ฒ๊ณผ๋ ๋ค์ ์ฐจ์ด๊ฐ ์์ต๋๋ค. Product 1,2,3 ์ด ์์ต๋๋ค. ์ด ํ์ด์ง ์์ค๊ฐ ๋ฐ๋ก ์๋ฒ์์๋ถํฐ ๋ฐ๋ ์ค์ ์๋ต์ด๋ผ๋ ์ ์ ๊ธฐ์ตํ์๊ธธ ๋ฐ๋๋๋ค. ์ด ๊ฒฝ์ฐ์๋ ํ์ด์ง๊ฐ ๋ก๋ฉ๋ ๋์ ๊ฐ๋ฐ ์๋ฒ์์ ๋ฐ๋ ๊ฒ์ ๋๋ค. ์ด ์์ฒญ์ด ์ฒ์ ์ ์ก๋ ์๋ฒ์ ๋๋ค. ๋ฐ๋ก ์ด ์ฝํ ์ธ ๋ฅผ ๊ฒ์ ์์ง์ด ๋ณด๊ฒ ๋๋ ๊ฒ์ ๋๋ค. ์ฝํ ์ธ ๊ฐ ์ด๋ฏธ ํฌํจ๋์ด ์์ด SEO ๊ด์ ์์๋ ํ๋ฅญํฉ๋๋ค.
import Head from "next/head";
import Image from "next/image";
import styles from "../styles/Home.module.css";
function HomePage(props) {
return (
<ul>
<li>Product 1</li>
<li>Product 2</li>
<li>Product 3</li>
</ul>
);
}
export default HomePage;
<!DOCTYPE html><html><head><style data-next-hide-fouc="true">body{display:none}</style><noscript data-next-hide-fouc="true"><style>body{display:block}</style></noscript><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills.js?ts=1668347788930"></script><script src="/_next/static/chunks/webpack.js?ts=1668347788930" defer=""></script><script src="/_next/static/chunks/main.js?ts=1668347788930" defer=""></script><script src="/_next/static/chunks/pages/_app.js?ts=1668347788930" defer=""></script><script src="/_next/static/chunks/pages/index.js?ts=1668347788930" defer=""></script><script src="/_next/static/development/_buildManifest.js?ts=1668347788930" defer=""></script><script src="/_next/static/development/_ssgManifest.js?ts=1668347788930" defer=""></script><noscript id="__next_css__DO_NOT_USE__"></noscript></head><body><div id="__next"><ul><li>Product 1</li><li>Product 2</li><li>Product 3</li></ul></div><script src="/_next/static/chunks/react-refresh.js?ts=1668347788930"></script><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"development","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
Next.js๋ ๋์ ๋ฐ์ดํฐ๊ฐ ์๋ ๋ชจ๋ ํ์ด์ง๋ฅผ ์ฌ์ ๋ ๋๋งํฉ๋๋ค.
91. getStaticProps ์ถ๊ฐํ๊ธฐ
getStaticProps ํจ์๋ ๋ชจ๋ ํ์ด์ง ํ์ผ์ ์ถ๊ฐํ ์ ์๊ณ ํ์ด์ง์๋ง ์ถ๊ฐํ ์ ์์ผ๋ฉฐ ๋ด๋ณด๋ด์ผ(export) ํฉ๋๋ค. ๊ทธ๋ ๊ฒ ํ๋ฉด Next.js๊ฐ ํ์ด์ง๋ฅผ ์ฌ์ ์์ฑํ ๋ ์ฌ์ฉ์๋ฅผ ๋์ ํ์ฌ ์ด getStaticProps ํจ์๋ ํธ์ถํฉ๋๋ค. ์ด ํจ์๋ ์ด ํ์ด์ง๊ฐ ์ฌ์ ์์ฑ๋์ด์ผ ํ๋ ํ์ด์ง์์ Next.js์ ์๋ ค์ค๋๋ค. Next.js๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋ชจ๋ ํ์ด์ง๋ฅผ ์ฌ์ ๋ ๋๋งํ์ง๋ง ์ดํ์ Next.js๊ฐ ํ์ด์ง๋ฅผ ์ฌ์ ์ ๋ ๋๋งํ์ง ์๊ฒ ํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋๋ค. Next.js๋ ์ปดํฌ๋ํธ๋ฅผ ์คํํ๊ณ JSX ์ฝ๋๋ฅผ ๋ฐํํ๋ ๊ฒ ์ธ์๋ ์ปดํฌ๋ํธ ํ์ผ์์ getStaticProps ํจ์๋ฅผ ์ฐพ์ผ๋ฉด ๊ทธ ํจ์๋ ํธ์ถํฉ๋๋ค. ํ์ค React ์ฑ์์ ์ํํ๋ ๋ฐฉ์ useEffect๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋ก๋ํด ๋ณด๊ฒ ์ต๋๋ค.
์ด ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ๊ธฐ ์ ์ ๊ทธ๋ฆฌ๊ณ Next.js๊ฐ ์ด ์ปดํฌ๋ํธ ํ์ด์ง๋ฅผ pre-Rendering ํ๊ธฐ ์ ๋ฐ์ดํฐ๋ฅผ ํ๋ฆฌํ์นํด์ผ ํฉ๋๋ค. ๊ทธ๋์ export async function getStaticProps()์ผ๋ก getStaticProps๋ผ๋ ํจ์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ๋๋ค. ํจ์ ์ด๋ฆ์ด getStaticProps๋ผ์ props ํค๊ฐ ์๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ผ ํ๊ณ ์ด ํจ์๊ฐ ํ๋ ์ผ์ ์ปดํฌ๋ํธ์ ๋ํ ํ๋กํผํฐ๋ฅผ ์ค๋นํ๋ ๊ฒ๋๋ค.
export async function getStaticProps() {
return {
props: {
products: [{ id: "p1", title: "Product 1" }],
},
};
์ฆ ์ด props ๊ฐ์ฒด๋ฅผ ์ค๋นํ๋ ๊ฑฐ์ฃ . ํ์ผ์ getStaticProps ํจ์๊ฐ ์์ผ๋ฉด Next.js์์ ๋จผ์ ์ด ํจ์๋ฅผ ์คํํ๊ณ ๋ ๋ฒ์งธ๋ก ์ปดํฌ๋ํธ ํจ์๋ฅผ ์คํํฉ๋๋ค. ์ฒซ ๋ฒ์งธ ๋จ๊ณ์์ ์ปดํฌ๋ํธ ํจ์์ ๋ํ props๋ฅผ ์ค๋นํ๊ธฐ ๋๋ฌธ์ด์ฃ . ๋ฐ๋ผ์ getStaticProps ํจ์์์๋ ์ํ๋ ์ฝ๋๋ฅผ ์ ํ ์์ด ์คํ ๊ฐ๋ฅํ๊ณ ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์๋ ์ ๋ ๋ณผ ์ ์๋ ์ฝ๋๋ก ๋ฐ์ดํฐ๋ฅผ fetchingํ๊ณ ์ด HomePage ์ปดํฌ๋ํธ์ props๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ค ์ ์์ต๋๋ค.
๊ทธ๋์ ์ฌ๊ธฐ์ props๋ฅผ ๊ฐ์ฒด์ ๋์ผํ๊ฒ ์ค์ ํด์ ์ปดํฌ๋ํธ๊ฐ ๋ฐ๋ props๊ฐ product ๋ถ๋ถ์์๋ ๊ฐ์ฒด๊ฐ ๋ฉ๋๋ค. ๊ทธ ๊ฐ์ฒด๋ ๊ฐ๋ น id: 'p1'์ด๊ณ title: 'Product 1'์ธ ์ด๋ฐ ์์ ๋ฐฐ์ด์ด ๋ ์ ์์ต๋๋ค. getStaticProps๋ props ํค๋ฅผ ํฌํจํ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ผ ํ๊ณ , ์ด๋ ํ์ ์ฌํญ์ ๋๋ค. ์ด ๊ฐ์ฒด๋ ๋ฐฐ์ด์ ๋ณด์ ํ๋ products ํค๊ฐ ์๋ ๊ฐ์ฒด์ด๊ณ ๋ฐฐ์ด์ Product ๊ฐ์ฒด์ ๋ฐฐ์ด์ด์ฃ . ๊ทธ๋ฆฌ๊ณ Next.js๊ฐ ๋จผ์ ์ด getStaticProps ํจ์๋ฅผ ํธ์ถํ๋ฉด ์ด ์ปดํฌ๋ํธ ํจ์๋ฅผ ์คํํ๊ธฐ ๋๋ฌธ์ ์ด HomePage์ props์์ ์ด๋ฅผ ์์ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ฌ์ ์ ๋ ๊ฐ์ง ์์ ์ ๋ชจ๋ ์ํํ๊ธฐ ๋๋ฌธ์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์๋ ์ด ์ฝ๋ ๋ชจ๋ ์คํ๋์ง ์์ต๋๋ค. ์ด ๋ชจ๋ ๊ฒ์ ๋น๋๋๋ ์๊ฐ ๋์ ํน์ ์ฌ์ฉ ์ค์ธ ์ด ๊ฐ๋ฐ ์๋ฒ์ ์ผ๋ถ๋ก ๊ฐ๋ฐ ์ค์ ๋ฐ์ํฉ๋๋ค.
Next.js ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ณด๋ฉด Product 1์ด ๋ณด์ ๋๋ค. ํ๋ ์ฝ๋ฉํ๊ธด ํ์ง๋ง ์ด๋ฏธ getStaticProps๋ฅผ ๊ตฌํํ ๊ฑฐ์ฃ . ์ด ํ์ด์ง์ ํ์ด์ง ์์ค๋ฅผ ๋ณด๋ฉด ์ด ๋ฐ์ดํฐ ์ด Product 1์ ๋ฐ์ดํฐ๋ ํด๋ผ์ด์ธํธ์๊ฒ ๋ณด๋ด์ง ํ์ด์ง์ ์ผ๋ถ์ ๋๋ค. ์ฆ Product ๋ฐ์ดํฐ ํ์นญ์ ํด๋ผ์ด์ธํธ์์ ๋ฐ์ํ์ง ์์์ต๋๋ค. ์๋ฒ์์ ๋ฐ์ํ ๊ฑฐ์ฃ .
๊ฐ๋ฐ์ ๋๊ตฌ์ Sources ํญ์ผ๋ก ๊ฐ์ JavaScript ์ฝ๋ ํ์ผ์ ๋ณด๋ฉด ์ด ์ฝ๋๋ ์๋ฌด ๊ณณ์์๋ ๋ณด์ด์ง ์์ ๊ฒ๋๋ค. ํด๋ผ์ด์ธํธ ์ฌ์ด๋์ ์ ๊ณต๋๋ ์ฝ๋๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด๋ getStaticProps์ ์ฝ๋๊ฐ ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์ ์คํ๋์ง ์๊ธฐ ๋๋ฌธ์ ์๋ฒ ์ธก ์์ ์ ์ํํ ์ ์์์ ์๋ฏธํฉ๋๋ค. ๋ฐ๋ผ์ ์ฌ์ฉ์๊ฐ ๋ณผ ์ ์๋ ํฌ๋ฆฌ๋ด์ (credential)์ ์ธ ์ ์๊ณ ์๋ฅผ ๋ค์ด ํ์ผ ์์คํ ์ ์ ๊ทผํ๋ ์ฝ๋์ ๊ฐ์ด ๋ธ๋ผ์ฐ์ ์์ ์๋ํ์ง ์๋๋ก ํ ์ ์์ต๋๋ค.
92. ์๋ฒ ์ฌ์ด๋ ์ฝ๋ ์คํํ๊ธฐ & FileSystem ์ฌ์ฉํ๊ธฐ
getStaticProps ๋ด๋ถ์ ๋ชจ๋ ์ฝ๋๊ฐ ์๋ฒ ์ฌ์ด๋์์ ์๋ฒ ์ฌ์ด๋ ๊ธฐ๋ฅ๊ณผ ํจ๊ป ์คํ๋๋ค๋ ์ ์ ํ์ฉํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
import path from "path";
import fs from "fs/promises";
export default function HomePage(props) {
const { products } = props;
return (
<ul>
{products.map((product) => (
<li key={product.id}>{product.title}</li>
))}
</ul>
);
}
export async function getStaticProps() {
const filePath = path.join(process.cwd(), "data", "dummy-backend.json");
const jsonData = await fs.readFile(filePath);
const data = JSON.parse(jsonData);
return {
props: {
products: data.products,
},
};
}
์ด ํจํค์ง๋ Node.js์ ํต์ฌ ๋ชจ๋์ ๋๋ค. ๋ธ๋ผ์ฐ์ ์ธก JavaScript๊ฐ ํ์ผ ์์คํ ์ ์ ๊ทผํ ์ ์๊ธฐ ๋๋ฌธ์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์๋ fs ๋ชจ๋ ์์ ์ด ์๋ฉ๋๋ค. ํนํ ์ด ํ๋ก์ ํธ ํ์ผ ์์คํ ์ ๋ฐฉ๋ฌธ์์๊ฒ ์ ๊ณต๋์ง ์์์ ์ ๊ทผํ์ง ๋ชปํฉ๋๋ค.
Next.js๋ ๋งค์ฐ ๋๋ํด์ getStaticProps๋ ๋์ค์ ๋ฐฐ์ฐ๋ ํจ์์์๋ง ์ฐ์ด๋ ์ํฌํธ๋ฅผ ํ์ธํ๊ณ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ์ฝ๋ ๋ฒ๋ค์์๋ ์ด ์ํฌํธ๋ฅผ ์ ๊ฑฐํฉ๋๋ค. ๋ฐ๋ผ์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ์ฝ๋ ๋ธ๋ผ์ฐ์ ์ธก React ์ฑ ์ฝ๋๊ฐ ์ค๋น๋ ๋ ๊ทธ ์ํฌํธ๋ ์ฌ๋ผ์ง๋๋ค Next.js๊ฐ ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์ ์ฌ์ฉํ์ง ์์์ ์๊ณ ์ฝ๋๋ฅผ ๋๋๋ ๊ฑฐ์ฃ .
๋ฐ๋ผ์ ์ผ๋ฐ์ ์ผ๋ก ์ปดํฌ๋ํธ ์ฝ๋๋ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ์ฝ๋์ ํฌํจ๋๊ณ ์ด ์ํฌํธ์ ์ด ์ฝ๋๋ ํฌํจ๋์ง ์์ต๋๋ค. ์ด์ fs๋ก ์ด dummy-backend.json ํ์ผ์ ์ก์ธ์คํ ์ ์์ต๋๋ค. fs.readFile์ด๋ readFileSync ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. readFileSync๋ ํ์ผ์ ๋๊ธฐ์ ์ผ๋ก ์ฝ๊ณ ์๋ฃ๋ ๋๊น์ง ์คํ์ ์ฐจ๋จํฉ๋๋ค. ๋ฐ๋ฉด์ readFile์ ๊ณ์ํ๋ ค๋ฉด ์ฝ๋ฐฑํด์ผ ํฉ๋๋ค. ํ๋ก๋ฏธ์ค๋ฅผ ์ฌ์ฉํ๋ Node.js ๋ชจ๋์ ํน์ ๋ฒ์ ์ธ fs/promises์์ ํ์ผ ์์คํ ์ ๊ฐ์ ธ์ฌ ์๋ ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด readFile์ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ํจ์๋ ๋น๋๊ธฐ ํจ์์ด๊ธฐ ๋๋ฌธ์ await์ ์์ ๋ถ์ฌ์ค๋๋ค. ์ด์ readFile์ ์ฝ์ด ์ค๋ ค๊ณ ํ๋ ํ์ผ์ ๊ฒฝ๋ก๋ง ์์ผ๋ฉด ๋ฉ๋๋ค. ์ฌ๊ธฐ์์ path๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค ์ด๋ฆ์ filePath๋ก ์ง์ ํ๊ฒ ์ต๋๋ค. ์ด ๊ฒฝ๋ก๋ dummy-backend.json ํ์ผ๋ก ์ฐ๊ฒฐ๋์ด์ผ ํฉ๋๋ค.
path ๋ชจ๋์ ๊ฒฝ๋ก๋ฅผ ๊ตฌ์ถํ๋ ๋ฐ ์ ์ฉํ ๊ธฐ๋ฅ์ด ์๋ ๋ชจ๋์ ๋๋ค. ์ฌ๊ธฐ์์ path๋ฅผ ์ฐ๊ณ join ๋ฉ์๋๋ฅผ ์คํํด์ readFile์ด ์ฌ์ฉํ ์ ์๋ ๊ฒฝ๋ก๋ฅผ ๊ตฌ์ถํ ์ ์์ต๋๋ค. Node.js์์ ์ ์ญ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ process ๊ฐ์ฒด๋ฅผ ํ์ฉํ์ฌ process์ cwd ๋ฉ์๋๋ฅผ ์คํํ ์ ์์ต๋๋ค. (cwd๋ ํ์ฌ ์์ ๋๋ ํ ๋ฆฌ๋ผ๋ ๋ป) ์ด ํ์ผ์ด ์คํ๋ ๋ Next.js๊ฐ ์ด๋ฅผ ์คํํ๊ณ ๋ชจ๋ ํ์ผ์ด ๋ฃจํธ ํ๋ก์ ํธ ํด๋์ ์๋ ๊ฒ์ฒ๋ผ ์ทจ๊ธํฉ๋๋ค.
๋ฐ๋ผ์ ํ์ฌ ์์ ๋๋ ํ ๋ฆฌ๋ pages ํด๋๊ฐ ์๋ ์ ์ฒด ํ๋ก์ ํธ ํด๋๊ฐ ๋ฉ๋๋ค. ๋ฐ๋ผ์ cwd๋ก Node.js path.join ๋ฉ์๋์ ์ด ์ ์ฒด ํ๋ก์ ํธ ๋๋ ํ ๋ฆฌ์์ ์์ํ๋ค๊ณ ์๋ ค์ฃผ๊ณ ์ผํ๋ฅผ ์ถ๊ฐํฉ๋๋ค. ๋ค์ ์ธ์๋ data ํด๋๋ก ๊ฐ์ผํ๊ธฐ ๋๋ฌธ์ 'data'์ ๋๋ค.
JSON ํ์ผ์์ jsonData๋ฅผ ๊ฐ์ ธ์ค๊ณ ์ค์ ๋ฐ์ดํฐ(data)๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด JSON.parse(jsonD)๋ฅผ ์ ๋ ฅํฉ๋๋ค. JSON์ ์ ์ญ์ ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฐ์ฒด๊ณ ๋ธ๋ผ์ฐ์ ์ธก์์์ ๋ง์ฐฌ๊ฐ์ง๋ก Node.js์์๋ ์ธ ์ ์์ต๋๋ค ์ด๊ฒ์ jsonData๋ฅผ ํ์ฑํ๊ณ ์ผ๋ฐ JavaScript ๊ฐ์ฒด๋ก ๋ณํํฉ๋๋ค. ์ด์ data๋ ๋ฐฐ์ด์ ํฌํจํ๋ products ํค๊ฐ ์๋ ๊ฐ์ฒด๊ฐ ๋ฉ๋๋ค. ์ด์ ์ด data๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ props๋ฅผ ๋ฐํํ ์ ์์ต๋. props์ ํฌํจ๋ products๋ data.products๊ฐ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ด ํ์ผ์์ ํ์นํ products๋ ์ด์ ์ด ๊ฐ์ฒด์ products์ ๊ฐ์ผ๋ก ์ ๋ฌ๋๋ฏ๋ก ๊ถ๊ทน์ ์ผ๋ก Next.js๊ฐ ์ด ํจ์๋ฅผ ์คํํ ๋ ์ด ์ปดํฌ๋ํธ ํจ์์ props๋ฅผ ํตํด ์ ๋ฌ๋ฉ๋๋ค. ํ์ง๋ง ๋จผ์ ์ด ํจ์๋ฅผ ๊ฑฐ์น๊ฒ ๋ฉ๋๋ค. ์ด์ ๋ชจ๋ ๊ฒ์ ์ ์ฅํ๊ณ localhost:3000์ ์๋ก ๊ณ ์นจํ๋ฉด ์ฌ๊ธฐ์ ์ธ ๊ฐ์ Product๊ฐ ํ์๋ฉ๋๋ค ํ์ด์ง ์์ค๋ก ๋์๊ฐ ๋ณด๋ฉด ์ฒ์๋ถํฐ ๋ชจ๋ ๋ฐ์ดํฐ๊ฐ ์๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ์ฌ์ ๋ ๋๋ง ๋์์ต๋๋ค.
ํด๋ผ์ด์ธํธ์ ๋๋ฌํ์ง ์๋ ์๋ฒ ์ฌ์ด๋ ์ฝ๋๋ฅผ ์คํํ๋ getStaticProps์ ๋์์ผ๋ก ์ฌ์ ๋ ๋๋ง ๋์์ต๋๋ค. ์ด๋ Next.js๊ฐ ํ์ด์ง๋ฅผ ์ฌ์ ๋ ๋๋งํ ๋๋ง ์คํ๋ฉ๋๋ค.
93. ๋ด๋ถ์์ ์ผ์ด๋๊ณ ์๋ ์ผ
build ์คํฌ๋ฆฝํธ๋ฅผ ์คํํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
npm run build
Route (pages) Size First Load JS
โ โ / 404 B 79.3 kB
โ /_app 0 B 78.9 kB
โ โ /404 212 B 79.1 kB
โ λ /api/hello 0 B 78.9 kB
+ First Load JS shared by all 79.1 kB
โ chunks/framework-aefaf282dc32bbc7.js 45.7 kB
โ chunks/main-5cebf592faf0463a.js 31.8 kB
โ chunks/pages/_app-aba2de2b7ae6fcb3.js 390 B
โ chunks/webpack-2369ea09e775031e.js 1.02 kB
โ css/49861c0d8668ac82.css 185 B
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
โ (Static) automatically rendered as static HTML (uses no initial props)
โ (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
โ : ์ ์ ์์ฑ์ ์๋ฏธํฉ๋๋ค. getStaticProps๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ ๋๋ ๋น๋ ํ๋ก์ธ์ค ์ค์ ์ฌ์ ์์ฑ๋ ํ์ด์ง์ ๋๋ค.
โ : ์ ์ ์ฆ ๋ชจ๋ ํ์ด์ง๊ฐ ์ฌ์ ์์ฑ๋์ง๋ง, ๋ฐ์ดํฐ๊ฐ ํ์ํ์ง ์์ผ๋ฏ๋ก getStaticProps๋ ์ด์ ์ ์ฌํ ๊ฒ์ ์ฐ์ง ์์ ํ์ด์ง์ ๋๋ค.
์ฌ์ ์์ฑ๋ ๋ ํ์ด์ง๊ฐ ์์ ํ์ด์ง์ด๋ฏ๋ก /๋ค์ ์๋ฌด๊ฒ๋ ์๋ index.js๊ฐ ์๊ณ . 404 ํ์ด์ง๊ฐ ์์ต๋๋ค. ์ถ๊ฐํ์ง ์์์ง๋ง ์๋ ์์ฑ๋์์ต๋๋ค. 404 ํ์ด์ง์ โ ๋ ์๋ฌด๋ฐ ๋ฐ์ดํฐ ์์ด ์ฌ์ ์์ฑ๋์๋ค๋ ์๋ฏธ์ ๋๋ค. index.js๋ getStaticProps๋ก ์ ์ ์ฌ์ ์์ฑ๋์์ผ๋ฏ๋ก โ ์ด ์์ต๋๋ค.
.next ํด๋ ์์ server ํด๋๊ฐ ์์ต๋๋ค. ์ฌ๊ธฐ์ ์ฌ์ ์์ฑ๋ HTML ํ์ผ์ ํ์ธํ ์ ์์ต๋๋ค. ๋ธ๋ผ์ฐ์ ์์ ์ด ํ์ด์ง๋ฅผ ๋ฐฉ๋ฌธํ๋ฉด ๋ณด์ผ pre-renders ํ์ด์ง์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฒ์ ์์ง ํฌ๋กค๋ฌ๋ ํ์ด์ง์ ๋ฐฉ๋ฌธ์์๊ฒ ์ด๊ธฐ ์์ฒญ์ผ๋ก ๋ค์ ๋ณด๋ด์ง๋ ์ฌ์ ์์ฑ๋ ํ์ด์ง์ ๋๋ค.
์๋ ๋ช ๋ น์ด๋ฅผ ์คํํ์ฌ ํ๋ก๋์ ์ค๋น ํ์ด์ง๋ฅผ ๋ฏธ๋ฆฌ ๋ณผ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ํ์ด์ง ํ๋ก๋์ ์ ์ํด ์๊ฒฉ ์ปดํจํฐ๋ก ์ํํ๊ธฐ๋ ํ์ง๋ง, ๊ฐ๋ฐ์ ์ปดํจํฐ๋ก ๋ก์ปฌ ์ํํ ์๋ ์์ต๋๋ค. localhost:3000์์ ์์ํ์ง๋ง ์ง๊ธ์ ๊ฐ๋ฐ ์๋ฒ๊ฐ ์๋๋ผ ํ๋ก๋์ ์ค๋น ํ์ด์ง๋ฅผ ์ ๊ณตํ๋ ์ค์ ์๋ฒ์ ๋๋ค.
โ nextjs-pre-rendering git:(main) npm start
> nextjs-pre-rendering@0.1.0 start
> next start
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
94. Incremental Static Generation (ISR) ํ์ฉํ๊ธฐ
๋ง์ฝ ์์ฃผ ๋ฐ๋๋ ๋ฐ์ดํฐ๋ผ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ์๋ก ํ์ด์ง๊ฐ ๋ฐฐํฌ๋ ํ ๋ค๋ฒ์งธ product๋ฅผ ์ถ๊ฐํ๋ฉด ํ์ด์ง๋ฅผ ๋ค์ ๋น๋ํ๊ณ ๋ค์ ๋ฐฐํฌํด์ผ ํฉ๋๋ค.
- ์ฒซ ๋ฒ์งธ ์๋ฃจ์ ์ ํ์ด์ง๋ฅผ ์ฌ์ ๋น๋ํ์ง๋ง, ์๋ฒ์์ ์ ๋ฐ์ดํธ๋ ๋ฐ์ดํฐ fetching์ ์ํด useEffect๋ฅผ ์ฌ์ฉํ๋ React ์ฝ๋๋ฅผ ํฌํจํ๋ ๊ฒ์ ๋๋ค.
- ๋๋ฒ์งธ๋ Nexct.js์ ISR์ ํ์ฉํ๋ ๊ฒ์ ๋๋ค. ํ์ด์ง๋ฅผ ๋น๋ํ ๋ ์ ์ ์ผ๋ก ํ ๋ฒ๋ง ์์ฑํ๋ ๊ฒ์ด ์๋๋ผ ๋ฐฐํฌ ํ์๋ ์ฌ๋ฐฐํฌ ์ ์ด ๊ณ์ ์ ๋ฐ์ดํธ ๋๋ค๋ ๋ป์ ๋๋ค. ์๋ก 60์ด ๋ง๋ค์ผ ๊ฒฝ์ฐ, ํน์ ํ์ด์ง์ ๋ํ ์์ฒญ์ด ์๊ณ , ๋ง์ง๋ง์ผ๋ก ์ฌ์์ฑ๋ ํ 60์ด๊ฐ ์ง๋์ง ์์๋ค๋ฉด ๊ธฐ์กด ํ์ด์ง๊ฐ ๋ฐฉ๋ฌธ์์๊ฒ ์ ๊ณต๋๋ค๋ ๊ฒ์ ๋๋ค. ์๊ฐ์ ์ ํ๊ธฐ ๋๋ฆ์ ๋๋ค.
export async function getStaticProps() {
console.log("(Re-) Generating...");
const filePath = path.join(process.cwd(), "data", "dummy-backend.json");
const jsonData = await fs.readFile(filePath);
const data = JSON.parse(jsonData);
return {
props: {
products: data.products,
},
revalidate: 10,
};
}
revalidate๋ฅผ ์ด์ฉํ์ฌ Next.js๊ฐ ์ด ํ์ด์ง๋ฅผ ์ฌ์์ฑํ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํ๋ ์๊ฐ์ ์ด ๋จ์๋ก ์ค์ ํฉ๋๋ค. ์ซ์๊ฐ ๋์์๋ก ์ด ํ์ด์ง๊ฐ ๋ค์ ์์ฑ๋๋ ํ์๋ ์ค์ด๋ญ๋๋ค. ํญ์ ๋ด์ฉ์ด ๋ฐ๋๋ ๋งค์ฐ ๋์ ์ธ ํ์ด์ง๋ 1์ด์ ๊ฐ์ด ๋งค์ฐ ์์ ๊ฐ์ ๋ฃ์ด์ผ ํฉ๋๋ค. dev ํ๊ฒฝ์๋ revalidate ๊ฐ๊ณผ ์๊ด์์ด ๋งค๋ฒ ํ์ด์ง๋ฅผ ์ฌ์์ฑํฉ๋๋ค. prod ํ๊ฒฝ์์๋ ๊ฐ์ ๋ฐ๋ผ ๋ณํ ๊ฒ์ ๋๋ค.
95. ISR ๋ด๋ถ์์ ์ผ์ด๋๋ ์ผ
โ nextjs-pre-rendering git:(main) โ yarn run build
yarn run build
yarn run v1.22.11
$ next build
info - Linting and checking validity of types
info - Creating an optimized production build
info - Compiled successfully
info - Collecting page data
[ ] info - Generating static pages (0/3)(Re-) Generating...
info - Generating static pages (3/3)
info - Finalizing page optimization
Route (pages) Size First Load JS
โ โ / (ISR: 10 Seconds) 404 B 79.3 kB
โ /_app 0 B 78.9 kB
โ โ /404 212 B 79.1 kB
โ λ /api/hello 0 B 78.9 kB
+ First Load JS shared by all 79.1 kB
โ chunks/framework-aefaf282dc32bbc7.js 45.7 kB
โ chunks/main-5cebf592faf0463a.js 31.8 kB
โ chunks/pages/_app-aba2de2b7ae6fcb3.js 390 B
โ chunks/webpack-2369ea09e775031e.js 1.02 kB
โ css/49861c0d8668ac82.css 185 B
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
โ (Static) automatically rendered as static HTML (uses no initial props)
โ (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
(ISR) incremental static regeneration (uses revalidate in getStaticProps)
ISR: 10์ด๋ฅผ ํตํด 10์ด๋ง๋ค ์ฌ์์ฑ ๋์ด์ผ ํ๋ค๋ ๊ฒ์ ์๊ณ ์์์ ๋ปํฉ๋๋ค. ๋น ๋ฅด๊ฒ ๋ช ๋ฒ์ ์๋ก ๊ณ ์นจํ๋ฉด ์์ง 10์ด๊ฐ ์ง๋์ง ์์๊ธฐ ๋๋ฌธ์ (Re-)Generating..์ด ๋์ค์ง ์์ต๋๋ค.
96. "getStaticProps" ๊ตฌ์ฑ ์ต์ ์ดํด๋ณด๊ธฐ
nonFound๋ฅผ ture๋ก ์ค์ ํ๋ฉด ํ์ด์ง๊ฐ 404 ์ค๋ฅ๋ฅผ ๋ฐํํ๋ฉฐ ์ผ๋ฐ ํ์ด์ง ๋์ ์ 404 ์ค๋ฅ ํ์ด์ง๋ฅผ ๋ ๋๋งํฉ๋๋ค. ์ด ํค๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ์ด๋ค ์ด์ ๋ก๋ ํจ์นญ์ ์คํจํ๋ฉด, ๊ทธ ์์ ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ฆ ์ํ์ด ์์ ๋๋ง notFound๋ฅผ true๋ก ์ค์ ํด์ notFound ํ์ด์ง๋ฅผ ํ์ํฉ๋๋ค. ๋ง์ฝ ํจ์น๋ ๋ฐ์ดํฐ์์ ์ํ์ด ํ๋๋ผ๋ ์์ผ๋ฉด ์ผ๋ฐ ํ์ด์ง๋ฅผ ๋ฐํํฉ๋๋ค.
if (data.products.length === 0) {
return { notFound: true };
}
redirect ํค๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ์ฉ์๋ฅผ ๋ฆฌ๋๋ ์ ํ ์ ์์ต๋๋ค. ์ฆ ํ์ด์ง ์ฝํ ์ธ ๋ ์ปดํฌ๋ํธ ์ฝํ ์ธ ๋ฅผ ๋ ๋๋งํ์ง ์๊ณ ๋ค๋ฅธ ํ์ด์ง, ์ฆ ๋ค๋ฅธ ๋ผ์ฐํธ๋ก ๋ฆฌ๋๋ ์ ํ๋ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด ๋ฐ์ดํฐ ๋ฒ ์ด์ค ๋ฑ์ ์ก์ธ์คํ ์ ์๋ค๊ณ ํฉ์๋ค. ์ด๋ด ๋ ๋ฆฌ๋๋ ์ ์ ์คํํ ์ ์์ต๋๋ค.
if (!data) {
return {
redirect: {
destination: "/no-data",
},
};
}
์ง๊ธ์ ์ด ๋๊ฐ์ง ์ต์ ์ ์ฌ์ฉํ ์ผ์ ์์ง๋ง, ์๊ณ ์๋ ๊ฒ์ด ์ข์ต๋๋ค :-)
97. ๋์ ๋งค๊ฐ๋ณ์ ์์ ํ๊ธฐ
๋ชจ๋ ์ํ์๋ ์ค๋ช ์ด ์๋ค๊ณ ๊ฐ์ ํด ๋ด ์๋ค. ๋ชจ๋ ์ํ์ ํด๋ฆญ ๊ฐ๋ฅํ ๋งํฌ๋ผ์ ์์ธ ํ์ด์ง๋ก ์ด๋ํ ์ ์์ต๋๋ค. ๊ฑฐ๊ธฐ์ ์ํ ์ค๋ช ์ ๋ณผ ์ ์์ต๋๋ค. ์ํ ์์ธ ํ์ด์ง๋ฅผ ์ถ๊ฐํ๊ณ (pid[].js) ๋๊ดํธ๊ฐ ์๋ ๋์ ์ธ๊ทธ๋จผํธ๋ฅผ ๋ง๋ค๋ฉด ๋ฉ๋๋ค. React์์ ์ํฌํธํ useEffect๋ฅผ ์ฌ์ฉํด์ ์ด ์ํ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ ์๋ฒ์ HTTP ์์ฒญ์ ๋ณด๋ผ ์ ์์ง๋ง ํ์ด์ง๊ฐ ์ฒ์ ๋ ๋๋ง ๋์ด ๋ฐ์ดํฐ๊ฐ ์๋ค๊ณ ์๊ฐํด ๋ด ์๋ค. ๊ทธ๋ฌ๋ฉด ๊ฒ์ ์์ง์ด ๋ณผ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์์ async ํ๋กํผํฐ ํจ์๋ฅผ ๋ค์ ์ฌ์ฉํ ๊ฒ๋๋ค.
export async function getStaticProps()
ํ์ผ ์ ์ฒด๋ฅผ ์ฝ๊ณ ๋ชจ๋ ์ํ์ ๋ฐํํ๊ธฐ๋ณด๋ค ํ์ผ์ ์ฝ๊ณ ๊ฑฐ๊ธฐ์ ํ๋์ ์ํ๋ง ๋ฐํํ๊ฒ ์ต๋๋ค. ๋ฐ๋ผ์ ๋น์ฐํ ์ด๋ค ์ํ์ด ์ฌ๊ธฐ์ ๋ฐํ๋ ์ง ์์์ผ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ์ํ์ ๊ฒฐ์ ํ๊ธฐ ์ํด์ URL์ ์๋ ๊ตฌ์ฒด์ ์ธ ๊ฐ์ ์ดํด๋ณด์์ผ ํฉ๋๋ค. ์ฆ pid ํค์ ๋ํ ๊ตฌ์ฒด์ ์ธ ๊ฐ์ด ๋๊ฒ ์ง์. ์ด๋ ์ฝํ ์คํธ(context) ๋งค๊ฐ๋ณ์๊ฐ ๋ค์ ์ค์ํด์ง๋๋ค. ์์ ์ ์ ์ธ๊ธํ์ง๋ง NextJS์ ์ํ ์ฝํ ์คํธ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌ์ฒด์ ์ธ ๋งค๊ฐ๋ณ์ ๊ฐ์ ๊ตฌํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ฆ ๊ฒฝ๋ก์์ ๋์ ์ธ๊ทธ๋จผํธ์ ๋ํ ๊ตฌ์ฒด์ ์ธ ๊ฐ์ ์ ์ ์์ต๋๋ค. ๊ทธ ๊ฐ์ ์ก์ธ์คํ๊ธฐ ์ํด context์ params ํค๋ฅผ ๋ด ์๋ค. NextJS๊ฐ ์ ๊ณตํ๋ context ๊ฐ์ฒด์ ํ๋กํผํฐ ์ค ํ๋์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ params(๋งค๊ฐ๋ณ์)๋ ํค-๊ฐ ์์ด ์๋ ๊ฐ์ฒด์ด๋ฉฐ ์ด๋ ํค์ ์๋ณ์๋ ๋์ ๊ฒฝ๋ก ์ธ๊ทธ๋จผํธ์ ๋๋ค. ์ด ๊ฒฝ์ฐ์๋ [pid]๊ฐ ๋ ๊ฒ๋๋ค. ํ์ด์ง์ ์ ์ผํ ๋์ ๋งค๊ฐ๋ณ์ ์ ๋๋ค.
์ฐ๋ฆฌ๋ ์ปดํฌ๋ํธ ํจ์์ useRouter ํ ์ ํตํด ๋งค๊ฐ๋ณ์๋ฅผ ์ถ์ถํ ์ ์์ต๋๋ค. ๊ฐ์ ๊ณผ์ ์ ์๋ถ๋ถ์์ ๋ค๋ฃจ์์ด์. userRouter ํ ์ ์ฌ์ฉํด์ router ๊ฐ์ฒด์ ์ก์ธ์คํ๊ณ router.query๋ก ๋งค๊ฐ๋ณ์๋ฅผ ์ถ์ถํ์ต๋๋ค. ์ปดํฌ๋ํธ ํจ์์ getStaticProps()์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ์ถํ ๋ ์ฐจ์ด์ ์ด ์์ต๋๋ค. ์ปดํฌ๋ํธ ํจ์์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ์ถํ๋ฉด ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค. ์ถ์ถ๋ ID๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ์ผ๋ถ ๋ฐฑ์๋ ์๋ฒ์ ์์ฒญ์ ๋ณด๋ด ๊ฑฐ๊ธฐ์์ ํ์นญํ๊ธฐ ์ํด์์ ๋๋ค. ํ์ง๋ง ์ด ๊ณผ์ ์ ๋ธ๋ผ์ฐ์ ์์๋ง ์ด๋ฃจ์ด์ง๋๋ค.
getStaticProps()๋ก ๋ฐ์ดํฐ๋ฅผ ์ค๋นํ์ฌ ํ์ด์ง๋ฅผ ์ฌ์ ๋ ๋๋งํ๊ฒ ๋๋ฉด ์ด ๊ฒฝ์ฐ๋ ์๋ฒ์์ ์ด๋ฃจ์ด์ง๋๋ค. ๊ทธ๋ฆฌ๊ณ getStaticProps๋ ์ปดํฌ๋ํธ ํจ์๋ณด๋ค ๋จผ์ ์คํ๋ฉ๋๋ค. ์ปดํฌ๋ํธ ํจ์๊ฐ ํ์ด์ง๋ฅผ ์ฌ์ ๋ ๋๋งํ๊ธฐ ์ํด ์คํ๋๋ ํจ์์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ทธ๋ฌ๋ฏ๋ก ์๋ฒ์์์ ํน์ getStaticProps๋ก ๊ตฌ์ถ ๊ณผ์ ์ค์ ํ์ด์ง๋ฅผ ๋ฏธ๋ฆฌ ์ค๋นํ๋ ค๋ฉด ๋งค๊ฐ๋ณ์๋ก์ ์ก์ธ์ค๊ฐ ํ์ํฉ๋๋ค. ์ฆ getStaticProps ๋ด๋ถ์ ๋์ ๊ฒฝ๋ก ์ธ๊ทธ๋จผํธ์ ์ก์ธ์คํด์ ๋งค๊ฐ๋ณ์ ๋ฐ์ดํฐ๋ฅผ ํตํด ์ปดํฌ๋ํธ์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ์ค๋นํด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ์ปดํฌ๋ํธ ํจ์ ์์๋ ๋์ ์ธ๊ทธ๋จผํธ๊ฐ ํ์ํ ๊ฒ ์๋๋ฉด ์ถ์ถํ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ทธ๋ฌ๋ ๋ฐ์ดํฐ ์ฌ์ ์ค๋น๋ getStaticProps์์ ํด์ผ ํ๋ฉฐ dummy-backend.json ํ์ผ์ ์ ๊ทผํด์ ํด๋นํ๋ ID๋ก ์ํ์ ์ฝ์ด์ผ ํฉ๋๋ค. ๋ค์ ๊ฐ์ฒด ๊ตฌ์กฐ ๋ถํด๋ก loadedProduct๋ฅผ ์ถ์ถํ๋๋ฐ props์์ ์ป์ ์ ์์ผ๋ฏ๋ก ์ฌ๊ธฐ๋ props๋ฅผ ํ์ฉํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ํ ์ด๋ฆ์ ์ฝ์ ์ ์๋ loadedProduct.title ๋ํ ์ํ ์ค๋ช ์ญ์ loadProduct.description์ ๋๋ค. ํ ์คํธ๋ฅผ ์ํด ์์ธ ํ์ด์ง๋ก ์ด๋ํ ์ ์๋์ง ๋ด ์๋ค. index.js ํ์ผ์ ๋งํฌ๋ฅผ ์ถ๊ฐํ์ฌ ์์ ํฉ์๋ค. ๋งํฌ๋ฅผ ํด๋ฆญํ๋๋ ์๋ฌ๊ฐ ์๊น๋๋ค. 'getStaticPaths is required'
URL์ ์ธ์ฝ๋ฉ๋ ๊ตฌ์ฒด์ ์ธ ๊ฐ์ ์ก์ธ์คํ๋ ค๊ณ params๋ฅผ ์ฌ์ฉํ์ผ๋ฉฐ ๊ทธ๋ ๊ฒ ์ถ์ถ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ํ ๋ฐ์ดํฐ๋ฅผ ํ์นญํ๊ณ ์ปดํฌ๋ํธ์ ํ์ฉํ์ต๋๋ค. ์ ์ด๋ฐ ์ค๋ฅ๊ฐ ์๋์ง ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค.
98. ๋์ ํ์ด์ง๋ฅผ ์ํ "getStaticPaths" ๊ฐ์
export default function HomePage(props) {
const { products } = props;
return (
<ul>
{products.map((product) => (
<li key={product.id}>
<Link href={`/${product.id}`}>{product.title}</Link>
</li>
))}
</ul>
);
}
export default function ProductDetailPage() {
const { loadedProduct } = props;
return (
<Fragment>
<h1>{loadedProduct.title}</h1>
<p>{loadedProduct.description}</p>
</Fragment>
);
}
export async function getStaticProps(context) {
const { params } = context;
const productId = params.pid;
const filePath = path.join(process.cwd(), "data", "dummy-backend.json");
const jsonData = await fs.readFile(filePath);
const data = JSON.parse(jsonData);
const product = data.products.find((product) => product.id === productId);
return {
props: {
loadedProduct: product,
},
};
}
NextJS๋ ๊ธฐ๋ณธ์ ์ผ๋ก๋ ํ์ด์ง๋ฅผ ์ฌ์ ์์ฑํ์ง๋ง, ๋์ ํ์ด์ง์์๋ ๊ทธ๋ ์ง ์์ต๋๋ค. ์ฆ ์ปดํฌ๋ํธ ์ด๋ฆ์ ๋๊ดํธ๊ฐ ์์ ๋์ธ๋ฐ์. ํด๋น ํ์ด์ง๋ก ์ฐ๊ฒฐ๋๋ ๋์ ์ธ๊ทธ๋จผํธ๊ฐ ์๋ ๊ฒฝ์ฐ ๊ธฐ๋ณธ ๋์์ผ๋ก ํ์ด์ง๋ฅผ ์ฌ์ ์์ฑํ์ง ์์ต๋๋ค.
์ ๊ธฐ๋ณธ๊ฐ์ด ์๋๊น์? ์ด ํ์ด์ง๋ ํ๋๊ฐ ์๋๋ผ ์ฌ๋ฌ ํ์ด์ง๋ก ์ด๋ฃจ์ด์ง ๋๋ฌธ์
๋๋ค. ์ํ ID๋ง๋ค ์๋ก ๋ค๋ฅธ ํ์ด์ง์ ํ๋ ์ ๋ฐ HTML ์ฝํ
์ธ ๋ ๊ฐ๊ณ ๋ฐ์ดํฐ๋ง ๋ค๋ฅด๊ฒ ๊ตฌ์ฑ๋๋ ๊ฒ๋๋ค. ์ด ํ์ด์ง๋ p1๋ p2 p1000๋ก๋ ๋ก๋๋ ์ ์๋๋ฐ NextJS๋ ์ฌ์ ์ ๋์ ํ์ด์ง๋ฅผ ์ํด์ ์ผ๋ง๋ ๋ง์ ํ์ด์ง๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํด์ผ ํ๋์ง ์์ง ๋ชปํฉ๋๋ค. ๋์ ํ์ด์ง๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ ์์ฑ๋์ง ๋ชปํ๊ณ ๋์ ์๋ฒ์์ ํญ์ ๊ทธ๋ ๊ทธ๋ ์์ฑ๋ฉ๋๋ค.
๊ทธ๋์ ์ด์ ์๋ ์๋ํ์ง๋ง ํ์ฌ getStaticProps๋ฅผ ์ถ๊ฐํ ์ํ๋ผ ์๋ํ์ง ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ page ์ปดํฌ๋ํธ ํ์ผ์ ์ด ํจ์๋ฅผ ์ถ๊ฐํ๋ค๋ ๊ฒ์ ์ฌ์ ์ ํ์ด์ง๋ฅผ ๋ ๋๋งํ๋๋ก NextJS์ ์์ฒญํ๋ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค. index.js์์๋ ์ฐจ์ด๊ฐ ์์์ฃ ์ด์จ๋ ๊ธฐ๋ณธ๊ฐ์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค. ํ์ง๋ง ๋์ ํ์ด์ง์๋ ์ฐจ์ด์ ์ด ์๊น๋๋ค. ์์ ์ด์ผ๊ธฐํ ์ด์ ๋๋ฌธ์ ๊ธฐ๋ณธ๊ฐ์ด ์๋๋ผ์ ๊ทธ๋ ์ต๋๋ค.
NextJS๋ ์ผ๋ง๋ ๋๋ ํ์ด์ง๊ฐ ํ์ํ์ง ์ ์ ์๊ณ ์ฐ๋ฆฌ์๊ฒ ์ด๋ค ๋์ ์ธ๊ทธ๋จผํธ์ ๊ตฌ์ฒด์ ์ธ ๊ฐ์ด ํ์ํ์ง ๋ชจ๋ฆ
๋๋ค. ๋ฐ๋ผ์ ๋์ ๋ผ์ฐํธ์ ๊ฒฝ์ฐ NextJS๊ฐ ๋ ๋ง์ ์ ๋ณด๊ฐ ํ์ํฉ๋๋ค. ๋ํ ์ฐ๋ฆฌ๋ NextJS์ ์ด๋ค ๊ฒฝ๋ก๊ฐ ์์ฑ๋์ด์ผ ํ๋์ง ๋์ ํ์ด์ง์์ ์ด๋ค ์ธ์คํด์ค๊ฐ ์ฌ์ ์์ฑ๋ผ์ผ ํ๋์ง ์๋ ค์ค ์ ์์ต๋๋ค. NextJS์ ์๋ ค์ฃผ๋ ค๋ฉด ํ์ด์ง์ ์ถ๊ฐํ ๋ค๋ฅธ ํจ์, ์ฆ ํ์ด์ง ํ์ผ์ ์ถ๊ฐํ ์ ์๋ ๋ ๋ค๋ฅธ ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๊ฒ ๋ฐ๋ก ๋น๋๊ธฐ ํจ์์ธ getStaticPaths()์
๋๋ค. await ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๊ณ getStaticProps()์ฒ๋ผ page ์ปดํฌ๋ํธ ํ์ผ์๋ง ์ถ๊ฐํ ์ ์๋ ํจ์์
๋๋ค.
99. getStaticPaths ์ฌ์ฉํ๊ธฐ
getStaticPaths()๋ ๋์ ํ์ด์ง์ ์ด๋ค ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ง NextJS์ ์๋ ค์ค๋๋ค. ๊ทธ๋์ getStaticProps()์ฒ๋ผ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ผ ํ์ง๋ง ๊ฐ์ฒด์ ๊ฐ์ ์๋ก ๋ค๋ฆ
๋๋ค. paths ํค๊ฐ ์๋ ๊ฐ์ฒด์ฌ์ผ ํฉ๋๋ค.์ฆ ๊ฐ์ฒด๋ฅผ ๊ฐ์ง ๋ฐฐ์ด์ด ๋ฉ๋๋ค. ์ด ๊ฐ์ฒด์ params ํค๋ฅผ ์ถ๊ฐํด์ผ ํ๋ฉฐ, params๋ ์ฌ๋ฌ ํค-๊ฐ ์์ด ์๋ ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๊ฐ์ง ์ ์์ผ๊ณ ์ด๋, ํค๋ ์ด ํ์ด์ง๋ก ์ฐ๊ฒฐํ๋ ๊ฐ๊ฐ์ ๋์ ์ธ๊ทธ๋จผํธ ์๋ณ์์
๋๋ค. ๋ง์ฝ ํด๋๊ฐ ์ค์ฒฉ๋์ด ํด๋ ์ด๋ฆ๋ ๋์ ์ด๋ผ๋ฉด ์ฌ๋ฌ ์๋ณ์๋ฅผ ๊ฐ์ง ์ ์์ง๋ง ์ฌ๊ธฐ์๋ pid ํ๋๋ฟ์
๋๋ค. ๊ทธ ๊ฐ์ ํ์ด์ง๊ฐ ์์ฑ๋๊ธฐ ์ํ ๊ตฌ์ฒด์ ์ธ ๊ฐ์
๋๋ค.
์๋ฅผ ๋ค๋ฉด ์ด ํ์ด์ง๋ฅผ ์ธ ๋ฒ ์์ฑํ๋๋ฐ ์ด ๋์ ํ์ด์ง ์๋ณ์์ ๊ฐ์ p1, p2, p3์ด ๋ฉ๋๋ค. ๋ฐ๋ผ์ pid๋ฅผ p1์ผ๋ก ์ค์ ํ๊ณ ๋ฐ๋ณตํ๊ฒ ์ต๋๋ค. ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ถ๊ฐํด์ params๋ฅผ ๋ ๋ค๋ฅธ ๊ฐ์ฒด์ธ pid: 'p2'๋ก ์ค์ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ธ ๋ฒ์งธ๋ก ๋ฐ๋ณตํ ๊ฒ์. ์ด ๊ฐ์ฒด์์๋ params๋ฅผ p3๋ก ์ค์ ํ๊ฒ ์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋์ ํ์ด์ง๊ฐ ์ธ ๋ฒ ์ฌ์ ์์ฑ๋์ด์ผ ํ๋ฉฐ ์ธ ๊ฐ์ง ๊ฐ์ ๊ฐ์ง๋ค๋ ์ฌ์ค์ NextJS์ ์๋ฆด ์ ์์ต๋๋ค. NextJS๊ฐ ๊ฐ ID์ ๋ํด getStaticProps()๋ฅผ ์ธ ๋ฒ ํธ์ถํ๊ณ ๊ทธ๋ฐ ๋ค์ ์ด ํจ์ ๋ด๋ถ์์์ฒ๋ผ ํด๋น ID๋ฅผ ์ถ์ถํ ์ ์์ต๋๋ค. ์ด๊ฒ ์๋ํ๋ ค๋ฉด paths ๋ค์์ ๋ค๋ฅธ fallback ํค๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ๋์ค์ ๋ค์ ๋ค๋ฃจ๊ฒ ์ง๋ง ์ง๊ธ์ false๋ก ๋๊ฒ ์ต๋๋ค. NextJS๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ฌ์ ์์ฑํ๊ธฐ ๋๋ฌธ์ ์ ํํ ํ์ด์ง๊ฐ ํ์๋ฉ๋๋ค. getStaticPaths()๋ ๋์ ํ์ด์ง์ ์ด๋ค ๊ตฌ์ฒด์ ์ธ ์ธ์คํด์ค๋ฅผ ์ฌ์ ์์ฑํ ์ง ์๋ ค์ฃผ๋ ํจ์๋ผ๊ณ ํ ์ ์์ต๋๋ค.
100. "getStaticPaths" & Link Prefetching: Behind The Scenes
yarn build ๋ช ๋ น์ ์คํํด์ ํ๋ก๋์ ์ฉ์ผ๋ก ๊ตฌ์ถํ๊ฒ ์ต๋๋ค.
โ nextjs-pre-rendering git:(main) yarn build
yarn run v1.22.17
$ next build
info - Linting and checking validity of types
info - Creating an optimized production build
info - Compiled successfully
info - Collecting page data
[ ] info - Generating static pages (0/6)(Re-) Generating...
info - Generating static pages (6/6)
info - Finalizing page optimization
Route (pages) Size First Load JS
โ โ / (ISR: 10 Seconds) 2.84 kB 81.7 kB
โ /_app 0 B 78.9 kB
โ โ /[pid] (619 ms) 449 B 79.4 kB
โ โ /p1
โ โ /p2
โ โ /p3
โ โ /404 212 B 79.1 kB
โ λ /api/hello 0 B 78.9 kB
+ First Load JS shared by all 79.1 kB
โ chunks/framework-0f397528c01bc177.js 45.7 kB
โ chunks/main-5cebf592faf0463a.js 31.8 kB
โ chunks/pages/_app-aba2de2b7ae6fcb3.js 390 B
โ chunks/webpack-2369ea09e775031e.js 1.02 kB
โ css/49861c0d8668ac82.css 185 B
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
โ (Static) automatically rendered as static HTML (uses no initial props)
โ (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
(ISR) incremental static regeneration (uses revalidate in getStaticProps)
๋ช๋ช ํ์ด์ง๊ฐ ์ฌ์ ๋ ๋๋ง ๋์๊ณ ์ต์ข ์ ์ผ๋ก 5ํ์ด์ง๋ฅผ ์์ฑํ์ต๋๋ค. ์ฌ๋์๋ง ์๋ ํ์ด์ง์ธ ์์ ํ์ด์ง๋ฅผ ๋ด ์๋ค. ๋ฐ๋ก index.js ํ์ผ์ธ๋ฐ ์ ํจ์ฑ ์ฌ๊ฒ์ฌ ์๊ฐ์ด 10์ด์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ๋์ ํ์ด์ง๋ ์ธ ๊ฐ์ง ์ธ์คํด์ค๋ฅผ ์์ฑํ์ด์. ๊ฐ๊ฐ p1, p2, p3์ ๋๋ค ์ฌ๋ฌ๋ถ๋ ์์๋ค์ํผ getStaticPaths()์์ ๋ฐํ๋ ๋งค๊ฐ๋ณ์ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ด์ฃ . ๋ํ 404 ํ์ด์ง ์ญ์ ์ด์ ์ฒ๋ผ ์ฌ์ ์์ฑํ์ต๋๋ค.
server์ pages๋ก ๊ฐ๋ฉด ๋ค์ํ ๋งค๊ฐ๋ณ์์ ๋ํ HTML ํ์ผ์ด ์์ต๋๋ค. ๋งํฌ๋ฅผ ํตํด ํ์ด์ง๋ฅผ ์ด๋ํ๋ ค๋ ๊ฒฝ์ฐ ํด๋น ๋ฐ์ดํฐ๋ฅผ ์ฌ์ ๋ก๋ฉํ๋ JSON ํ์ผ๋ ๋ณผ ์ ์์ต๋๋ค. ์ฆ ์ด๊ธฐ ํ์ด์ง ๋ก๋ฉ ๋๊ฐ ์๋ ์ฐ๋ฆฌ๊ฐ ๊ทธ ํ์ด์ง์ ์์ ๋์ ๋๋ค. HTML ํ์ผ์ ์ดํด๋ณด๋ฉด ๊ฒฐ๊ตญ ์ฌ๊ธฐ ์ด๋๊ฐ์์ Product 1์ ํ ์คํธ๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ๋ฅผ ์ฌ์ ํ์นญํ๋ ๊ฒ๋ ๋ณด์ฌ๋๋ฆด ์ ์์ต๋๋ค. npm start๋ฅผ ์คํํด๋ด ์๋ค.
โ nextjs-pre-rendering git:(main) โ npm start
> nextjs-pre-rendering@0.1.0 start
> next start
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
(Re-) Generating...
(Re-) Generating...
(Re-) Generating...
๋ก์ปฌ ๋จธ์ ์์ ํด๋น ๋น๋ ํ๋ก์ ํธ๋ก ํ๋ก๋์ ์๋ฒ๋ฅผ ์์ํฉ์๋ค. ์๋ก ๊ณ ์นจํ๋ฉด ํด๋ฆญ ๊ฐ๋ฅํ ๋งํฌ๊ฐ ๋์ต๋๋ค. ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ์ด๊ณ Network ํญ์ผ๋ก ๊ฐ์ localhost: 3000์ ์๋ก ๊ณ ์นจํ๋ฉด ํฅ๋ฏธ๋ก์ด ๊ฒ ๋ณด์ด๋๋ฐ์,
p1.json, p2.json ๋ฐ p3.json์ ๋ํ ์์ฒญ์ด ์์ต๋๋ค. ๋งํฌ๋ฅผ ํด๋ฆญํ๋ฉด ์๋ก ๊ณ ์นจ ๋ ํ์ด์ง์ ๋ํ ํ๋กํผํฐ๊ฐ pre-fetching ๋์์์ ์ ์ ์์ต๋๋ค. ๋ง์ฐ์ค๋ฅผ ๋งํฌ์ ๊ฐ์ ธ๊ฐ๊ธฐ๋ ์ ์ ๋ฐ์ดํฐ๊ฐ pre-fetching ๋์์ต๋๋ค. ์ด๋ฏธ ํ์ด์ง์ ๋ค์ด์จ ์ํ๋๊น์. ๋ฐ์ดํฐ๊ฐ pre-fetching ๋๋ ์ ํํ ์์ ์ NextJS๊ฐ ๊ฒฐ์ ํ๊ณ ์คํํฉ๋๋ค. ์ค์ํ ๊ฑด NextJS๊ฐ pre-fetching ์ ํด์ค๋ค๋ ๊ฑฐ์ฃ . ์ด์ ๋งํฌ๋ฅผ ํด๋ฆญํ๋ฉด ์๋ฒ์ ์๋ก์ด ์์ฒญ์ ๋ณด๋ด์ ์ฌ์ ๋ ๋๋ง ๋ HTML ํ์ผ์ ๋ก๋ํ๋ ๊ฒ ์๋๋ผ ์ฑ๊ธ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ณ์ ๋จธ๋ฌด๋ฆ ๋๋ค.
์ด๊ธฐ ์์ฒญ ์ดํ, ๋ก๋ํ๊ณ ์ํ(hydrate)ํ๋ React ์ ํ๋ฆฌ์ผ์ด์ ์ ์๊ณ , ๊ทธ๋ฌ๊ณ ๋์ NextJS๊ฐ ์๋ ์ผ๋ฐ React ์ฑ์์์ฒ๋ผ JavaScript๊ฐ ์ ํ์ด์ง๋ฅผ ๋ ๋๋งํฉ๋๋ค. ์ด ํ์ด์ง์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ณณ์ ๋ฏธ๋ฆฌ fetching ๋ JSON ํ์ผ์ธ๋ฐ ์ฐ๋ฆฌ ๋์ ๋ก๋ฉํ๊ณ ์ฝ๊ธฐ๋ฅผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ์ฐ๋ฆฌ๊ฐ ํ์ด์ง๋ก ์ด๋ํ ํ ๋ฐ์ดํฐ๋ฅผ ํ์นญํ ํ์๊ฐ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ต์ข ์ ์ธ Product 1 ํ์ด์ง๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ํ์ํ ๋ ๋ฐ์ดํฐ๋ ์ด๋ฏธ ํจ์ฌ ๋น ๋ฅด๊ฒ ์กด์ฌํ๊ฒ ๋ฉ๋๋ค.
101. ๋์ฒด ํ์ด์ง ์์ ํ๊ธฐ
fallback ํค๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ์ ์์ฑ๋์ด์ผ ํ ํ์ด์ง๊ฐ ๋ง์ ๋ ๋์์ด ๋ฉ๋๋ค. ์ฌ๊ธฐ๋ ๋๋ฏธ ์ํ์ด ์ธ ๊ฐ๋ฐ์ ์์ต๋๋ค. Amazon์ฒ๋ผ ์ํ์ด ์๋ฐฑ๋ง ๊ฐ์ธ ์น ์ฌ์ดํธ๋ฅผ ์์ํด ๋ณด์ธ์. ๋ชจ๋ ์ํ์ ์ฌ์ ์์ฑํ๋ ๊ฒ์ด ๋ฌผ๋ก ์ต์ ์ ๋ฐฉ๋ฒ์ ์๋๋๋ค. ๋ค๋ง ๋ง์ ํ์ด์ง๋ฅผ ์ฌ์ ์์ฑํ๋ฉด ์๊ฐ์ด ๋๋ฌด ์ค๋ ๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ์ด์ฃ . ๊ทธ๋ฆฌ๊ณ ์ด๋ฐ ๊ฒฝ์ฐ๋ ์์ต๋๋ค. ๋ฐฉ๋ฌธ๊ฐ์ด ๊ฑฐ์ ์์ ๊ฒฝ์ฐ ์๋ฐฑ ๊ฐ์ ๊ฒ์๋ฌผ์ด ์๋ ๋ธ๋ก๊ทธ๋ฅผ ๋ง๋ค๋ฉด, ๊ทธ์ค ํ ๋ฒ๋ ์ฝํ์ง ์๋ ๊ฒ์๋ฌผ์ด ์์ ์ ์์ต๋๋ค. ๋ฐฉ๋ฌธ๊ฐ์ด ๊ฑฐ์ ์๋ ํ์ด์ง์ ์ฌ์ ์์ฑ์ ์๊ฐ๊ณผ ์์ ๋ญ๋น์
๋๋ค. ์ฌ๊ธฐ์ ํด๋ฐฑ(fallback) ๊ธฐ๋ฅ์ด ํ์ํ๋ฐ, true๋ก ์ค์ ํ๊ณ ์๋ฅผ ๋ค์ด ์ผ๋ถ ํ์ด์ง๋ง ์ฌ์ ๋ ๋๋งํ ์ ์์ต๋๋ค. ์ํ ID๊ฐ 1์ธ ํ์ด์ง๋ฅผ ์ฌ์ ๋ ๋๋งํ๋ค๊ณ ์๊ฐํด ๋ด
์๋ค. ์ฆ p1์ ์์ฃผ ์ฌ์ฉ๋๊ณ ๋ฐฉ๋ฌธ๊ฐ์ด ๋ง์ ํ์ด์ง๋ผ๊ณ ์๊ฐํด ๋ณด์ฃ . ํ์ง๋ง ๋ค๋ฅธ ๋ ํ์ด์ง๋ ์ฌ์ ์์ฑํ์ง ์๊ฒ ์ต๋๋ค.
fallback: true
Product 3์ ํด๋ฆญํ๋ฉด ์์ง ํ์ด์ง๊ฐ ์ ์์ ์ผ๋ก ๋ก๋ฉ๋ฉ๋๋ค. ์ฌ๊ธฐ์ paths์ ์ถ๊ฐํ์ง ์์๋ ์๋ํฉ๋๋ค. fallback: true๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๊ธฐ์ ํฌํจ๋์ง ์์ ํ์ด์ง๋ผ๋ ์ฆ pid ๋งค๊ฐ๋ณ์์ ๋ํ ๋งค๊ฐ๋ณ์ ๊ฐ์ด ์๋๋ผ๋ ํ์ด์ง ๋ฐฉ๋ฌธ ์ ๋ก๋ฉ๋๋ ๊ฐ์ด ์ ํจํ ์ ์๋๋ก NextJS์ ์์ฒญํ ์ ์์ต๋๋ค. ๋ค๋ง ์ฌ์ ์ ์์ฑ๋๋ ๊ฑด ์๋๊ณ ์์ฒญ์ด ์๋ฒ์ ๋๋ฌํ๋ ์๊ฐ ์์ ์ ์์ฑ๋ฉ๋๋ค. ์ด๋ฐ ์์ผ๋ก ๋ฐฉ๋ฌธ์จ์ด ๋์ ํ์ด์ง๋ฅผ ์ฌ์ ์์ฑํ ์ ์๊ฒ ๋๋ฉฐ ๋ฐฉ๋ฌธ์ด ์ ์ ํ์ด์ง๋ฅผ ์๋ฒ์ ์์ฑํ๋ ๊ฒ์ ๋ฏธ๋ค์ ํ์ํ ๊ฒฝ์ฐ์๋ง ์ฌ์ ์์ฑ๋๊ฒ ํ ์ ์์ต๋๋ค.
ํ์ง๋ง ๋ฌธ์ ๊ฐ ์๋๋ฐ์..! ๋งํฌ๋ฅผ ํด๋ฆญํ์ง ์๊ณ ์ง์ URL์ ์ง์ ์
๋ ฅํ์ฌ ์ด ํ์ด์ง์ ์๋ก์ด ์์ฒญ์ ๋ณด๋ด๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
์๋ฌ์ ์ด์ ๋ ๋์ ์ฌ์ ์์ฑ ๊ธฐ๋ฅ์ด ์ฆ์ ๋๋์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๋ฐ๋ผ์ fallback ๊ธฐ๋ฅ์ ์ฐ๋ ค๋ฉด ์ปดํฌ๋ํธ์์ ํด๋ฐฑ ์ํ๋ฅผ ๋ฐํํ ์ ์๊ฒ ํด์ค์ผ ํฉ๋๋ค. if (!loadedProduct)๋ก ์ฌ์ ์์ฑํ ๋ถ๋ถ์ด ์กด์ฌํ๋์ง ํ์ธํ๊ณ ๋ง์ฝ ์กด์ฌํ์ง ์๋๋ค๋ฉด Loading... ๊ฐ์ ๋ด์ฉ์ ๋ฐํํ๊ฒ ๋ง๋ค๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ผ ์ปดํฌ๋ํธ ํจ์์ ์ด๋ ๊ฒ ์ถ๊ฐํ๊ณ ์ ๋ถ ์ ์ฅํ๊ฒ ์ต๋๋ค. ์ด์ ์๋ก ๊ณ ์นจํ๋ฉด ์งง๊ฒ Loading์ด ๋ํ๋ฉ๋๋ค. ๋ก๋ฉ์ด ์๋ฃ๋๋ฉด NextJS๊ฐ ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธฐ๋ฅ์ useEffect์ setState๋ฅผ ์ฌ์ฉํ๋ ํ์ค React ์๋ฃจ์
๊ณผ ๋น์ทํ์ง๋ง ๊ฐ๋จํ์ฃ .
๋จ์ง ํ๋กํผํฐ๋ฅผ ํตํด ์ป๊ณ if()๋ก ์กด์ฌ๋ฅผ ํ์ธํด์ ์๋ ๊ฒฝ์ฐ์๋ ํด๋ฐฑ ์ฝํ
์ธ ๊ฐ ๋์ค๊ฒ ํ๋ฉด ๋๋ ๊ฑฐ์ฃ . ์กด์ฌํ ๊ฒฝ์ฐ NextJS๊ฐ ์๋์ผ๋ก ์ปดํฌ๋ํธ ํ์ด์ง๋ฅผ ์
๋ฐ์ดํธํ๊ณ ์ผ๋ฐ ์ฝํ
์ธ ๋ฅผ ๋ฐํํ๋ ๊ฒ๋๋ค. ๋ฐ๋ผ์ ํ์ด์ง๋ฅผ ์๋ก ๊ณ ์นจํ๋ฉด ๊ฒฐ๊ตญ ์ฑ๊ณต์ ์ผ๋ก ๋ก๋ฉ์ด ๋ฉ๋๋ค ํด๋ฐฑ ๊ธฐ๋ฅ ๋๋ถ์ด์ฃ .
fallback: blocking
ํด๋ฐฑ์ true๋ false๋ก ์ค์ ํ์ง ์๋ ๋์ blocking ๋ฌธ์์ด ๊ฐ์ผ๋ก ์ค์ ํ ๊ฒฝ์ฐ ์ปดํฌ๋ํธ์์ ํด๋ฐฑ ํ์ธ์ ํ ํ์๊ฐ ์์ต๋๋ค. ํ์ด์ง ๋ฐฉ๋ฌธ์๊ฐ ์๋ต๋ฐ๋ ์๊ฐ์ ๊ธธ์ด์ง์ง๋ง ์์ ๋ ์๋ต์ ์ข
๋ฃ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๋ค์ ์๋ก ๊ณ ์นจํด๋ ์๊ฐ์ด ๊ฑธ๋ฆด ๋ฟ ์ ์๋ํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ ํ์ํ ์ ๊ทผ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ๋ถ์ ์ ํ์ ๋ฌ๋ ค์์ต๋๋ค. ๋น ๋ฅด๊ฒ ๋ฌด์์ธ๊ฐ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ฒ ๋ ์ค์ํ ๋๊ฐ ์์ฃ . ํ์ด์ง ์์ฑ๊ณผ ๋ฐ์ดํฐ ํ์นญ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆด ๊ฒฝ์ฐ ํนํ ๊ทธ๋ ์ต๋๋ค. ๊ทธ๋ฐ ๊ฒฝ์ฐ blocking๊ณผ ๊ฐ์ ๋ฌธ์์ด์ด ๋์ ์๋ ์์ด์. ์ด๋ ๊ฒ ๋งค์ฐ ๊ฐ๋จํ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ๋ณด์ฌ๋๋ ธ์ต๋๋ค.
102. ๋์ ์ผ๋ก ๊ฒฝ๋ก ๋ก๋ฉํ๊ธฐ
getStaticPaths ํจ์์ ์ฝ๋๋ฅผ ์์ฑํด ๋ดค์ง๋ง ์ด๋๋ก ์ค์ ์์ ์ ์ ์ฉํ๊ธฐ๋ ๋ฌด๋ฆฌ๊ฐ ์์ต๋๋ค. ์ด pid ๊ฐ์ ํ๋ ์ฝ๋ฉํ์ผ๋๊น์. async function getData๋ฅผ ์์ฑํ๋๋ก ํ๊ฒ ์ต๋๋ค.
async function getData() {
const filePath = path.join(process.cwd(), "data", "dummy-backend.json");
const jsonData = await fs.readFile(filePath);
const data = JSON.parse(jsonData);
return data;
}
๊ฐ์ฒด๋ params์ ํค๋ฅผ ๊ฐ๊ณ ๊ทธ ์์๋ pid ํค๊ฐ ์๋ ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๊ฐ์ต๋๋ค. ์ด id๋ฅผ ๊ฐ์ผ๋ก ์ทจํฉ๋๋ค. ์ด๊ฒ ๋ชจ๋ ID์ ์ ์ฉ๋๋ฉด ๊ฐ์ฒด๋ก ๊ฐ๋ ์ฐฌ ๋ฐฐ์ด์ด ์์ฑ๋ฉ๋๋ค. ์ด๊ฒ ๋ฐ๋ก ์ด paths์ ํ์ํ ๊ตฌ์กฐ๋ก paths๋ฅผ params๋ก ์ค์ ํ ์ ์์ต๋๋ค.
export async function getStaticPaths() {
const data = await getData();
const ids = data.products.map((product) => product.id);
const pathWithParams = ids.map((id) => ({ params: { pid: id } }));
return {
paths: pathWithParams,
fallback: "blocking", // can also be true or 'blocking'
};
}
fallback์ ๋ค์ false๋ก ์ค์ ํ ์ ์์ต๋๋ค. ์์ฒญ ๊ฐ๋ฅํ ID์ ํ์ด์ง๋ฅผ ์ ๋ถ ๋ถ๋ฌ์ค๊ธฐ ๋๋ฌธ์ ๋๋ค.
103. ๋์ฒด ํ์ด์ง & "Not Found" ํ์ด์ง
fallback: false
pathsWithParams๋ ๋งค๊ฐ๋ณ์ ์๋ง ๊ตฌ์ฑํ๋ ๋ฐฐ์ด๋ก [pid]์ ๊ฐ์ผ๋ก๋ p1, p2, p3๋ฅผ ๊ฐ์ต๋๋ค. dummy-backend.js ํ์ผ์๋ ์ธ ๊ฐ์ง ID ๋ฐ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์ฌ์ ์์ฑ๋์ง ์์ ID์ ํ์ด์ง๋ฅผ ๋ถ๋ฌ์ฌ ๊ฒฝ์ฐ 404 ์๋ฌ ํ์ด์ง๊ฐ ๋น๋๋ค.
fallback: true
fallback์ true๋ก ์ค์ ํจ์ผ๋ก ํ์ผ์์ ์ฐพ์ ์ ์๋ ID์ ๋ํด์๋ ํ์ด์ง๋ฅผ ๋ ๋๋งํ ์ ์์ต๋๋ค. ์ด๊ฒ fallback์ ๊ฐ๋ ์ด๋ฉด์ ์๋ ๊ฑฐ์ฃ . ๋๋ถ์ ๋์ ์ธ๊ทธ๋จผํธ์ ๋ชจ๋ ๊ฐ์ ๋ํ ํ์ด์ง๋ฅผ ์ผ์ผ์ด ๋ค ์ฌ์ ์์ฑํ ํ์๊ฐ ์์ต๋๋ค. ์ด๋ ๊ฒ fallback์ true๋ก ์ค์ ํ๊ณ /p4๋ก ์ด๋ํ๋ฉด '์ ์๋์ง ์์ title ํ๋กํผํฐ๋ฅผ ์ฝ์ ์ ์๋ค'๋ ์๋ฌ ๋ฉ์์ง๊ฐ ๋น๋๋ค. fallback์ blocking์ด ์๋ true๋ก ์ค์ ํ์ ๋ Next.js๋ ์ฆ์ ๋ฐ์ดํฐ๊ฐ ์์ง ์๋ ํ์ด์ง๋ฅผ ๋ฐํํ๊ณ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์์ ํ์ด์ง๋ฅผ ๋ค์ ๋ ๋๋งํ๊ณ ํ๋ฉด์ ํ์ํฉ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ค๋ฆด ๋๋ ์ด ํด๋ฐฑ ํ์ด์ง๋ฅผ ๋ ๋๋ง ํด์ผ ํฉ๋๋ค.
if (!loadedProduct) {
return <p>Loading...</p>;
}
ํ์ง๋ง ์ด ์ญ์ ์๋ฌ๊ฐ ๋ฉ๋๋ค.
๋น์ฐํ ๊ฒฐ๊ณผ์ ๋๋ค. getStaticProps์์๋ dummy-backend.js ํ์ผ์ ์ ๊ทผํด ํด๋น ํ์ผ์์ ID ๊ฐ์ผ๋ก ์ํ์ ์ฐพ๋๋ฐ ์ด ํ์ผ์๋ p4์ ํด๋นํ๋ ์ํ์ด ์์ต๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ํด๋ฐฑ ํ์ด์ง์์ '๋ก๋ฉ ์ค' ๋ฉ์์ง๊ฐ ์ ๊น ๋จ๋ ๋์ NextJS๊ฐ ํด๋น ํ์ด์ง๋ฅผ ์ํด ์์ฒญํ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ํ๋ ค๊ณ ํ์ง๋ง ์ผ์นํ๋ ์ํ์ด ์์ผ๋ ์คํจํฉ๋๋ค.
๋ง์ฝ ์ํ์ ๋ถ๋ฌ์ค๋ ค๊ณ ํ ๋ ์ํ์ ์กด์ฌ ์ฌ๋ถ๋ฅผ ํ์ธํ ์๋ ์์ต๋๋ค.
export async function getStaticProps(context) {
const { params } = context;
const productId = params.pid;
const data = await getData();
const product = data.products.find((product) => product.id === productId);
if (!product) {
return { notFound: true };
}
return {
props: {
loadedProduct: product,
},
};
}
๋ง์ฝ ์ํ์ ๋ถ๋ฌ์ค๋ ค๊ณ ํ ๋ ์ํ์ ์กด์ฌ ์ฌ๋ถ๋ฅผ ํ์ธํ ์๋ ์๊ฒ ์ฃ . ์์ฒญํ ID์ ์ํ์ ์ฐพ์ง ๋ชปํ๋ฉด notFound๋ฅผ true๋ก ์ค์ ํ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๊ฒ ์ต๋๋ค. ์ด๋ ๊ฒ ์ค์ ํ๋ฉด fallback์ ์ฐธ์ผ๋ก ๋ ์ ์๊ณ ์ฌ์ ์ ์๋์ง ์์ ๋งค๊ฐ ๋ณ์ซ๊ฐ์ ๋ํ ์ํ์ ์ฐพ๊ธฐ ์ํ ์๋๋ฅผ ํ์ฃ . dummy-backend.js ํ์ผ์ํด๋น ์ํ์ ์์ฐํ ์ ์๋ ๋ณด๋ค ๋์ ์ธ ๋ฐ์ดํฐ ์์ค์ด๋๊น์. ๊ทธ๋ฆฌ๊ณ ๋ง์ฝ ํ์นญ์ ์คํจํ๋ค๋ฉด ์๋ฌ๋ฅผ ์ผ์ผํค๋ ๋ฐ์ดํฐ๊ฐ ๋๋ฝ๋ ์ผ๋ฐ ํ์ด์ง๋ฅผ ๋ฐํํ๋ ๋์ ์ ํ์ด์ง๋ฅผ ์ฐพ์ ์ ์๋ค๋ 404 ์๋ฌ ํ์ด์ง๋ฅผ ๋์ฐ๊ฒ ์ต๋๋ค. ์ด๋๋ก ์ ์ฅํ ํ /p4๋ก ์ด๋ํ๋ฉด '๋ก๋ฉ ์ค' ๋ฉ์์ง๊ฐ ๋จ๋ค๊ฐ 404 ์๋ฌ ํ์ด์ง๊ฐ ๋จ์ฃ . ๋ฐ๋ฉด /p3๋ก ์ด๋ํ๋ฉด ๋ค์ ์ ์์ ์ธ ํ์ด์ง๊ฐ ๋น๋๋ค. ์ด๋ ๊ฒ fallback์ true๋ก ์ค์ ํ getStaticProps์์ notFound ํ๋กํผํฐ๋ฅผ ํ์ฉํ ์ ์๊ฒ ์ฃ !
104. ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง (SSR)์ ์ํ getServerSideProps์ ๊ฐ์
getStaticProps์ getStaticPaths๋ฅผ ์ดํด๋ดค์ต๋๋ค. ์ด ๋ ํจ์๋ ํจ๊ป ์๋ํ์ง๋ง ํญ์ ๋ ๋ค ํ์ํ ๊ฑด ์๋์์. ์ด index.js ํ์ผ์๋ getStaticProps๋ง ํ์ํฉ๋๋ค. ํ์ง๋ง ์ฌ์ ์์ฑ ์ฌ์ ๋ ๋๋ง์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ๋ณด์ฌ ๋๋ ธ์ฃ . ์ ์ ์์ฑ(Static Generation)๊ณผ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)์ ๋๋ค. ์ง๊ธ๊น์ง ์ดํด๋ณธ ๊ฑด ์ ์ ์์ฑ์ ๋๋ค. ํ์ด์ง๋ฅผ ์ ์ ์ผ๋ก ์ฌ์ ์์ฑํ์ผ๋๊น์. getStaticProps์ getStaticPaths ๋ด๋ถ์์๋ ๋ค์ด์ค๋ ์ค์ ์์ฒญ์ ์ ๊ทผํ ์ ์์ต๋๋ค. ํ์ง๋ง ์ ์ ์์ฑ๋ง์ผ๋ก๋ ์ถฉ๋ถํ์ง ์์ ๋๊ฐ ์์ต๋๋ค. ์ด๋ด ๋ ์ค์ ๋ก ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ด ํ์ํฉ๋๋ค. ์ ์ ๋๋ ๋ชจ๋ ์์ฒญ์ ๋ํ ํ์ด์ง๋ฅผ ์ฌ์ ๋ ๋๋งํ๋ ๊ฑฐ์ฃ . ๋ฐ๋ผ์ ๋งค์ด๋ ์๋์ง๋ง ์ ์ ๋๋ ๋ชจ๋ ์์ฒญ์ ๋ํด์๋ ์๋ฒ์ ๋๋ฌํ๋ ํน์ ์์ฒญ ๊ฐ์ฒด์ ์ ๊ทผํ ํ์๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ฟ ํค(Cookie)๋ฅผ ์ถ์ถํด์ผ ํ๋ ๊ฒฝ์ฐ์ฃ . ์ถํ ์ธ์ฆ(Authentication)์ ๋ค๋ฃจ๋ ๊ฐ์์์ ์ค๋ช ํ ๋ด์ฉ์ด์ง๋ง ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์์ ์ค๋ช ํ๊ณ ์ถ๋ค์. NextJS๋ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ ์ํ ์ฝ๋๋ ์ง์ํฉ๋๋ค. ์ฆ ํ์ด์ง ์ปดํฌ๋ํธ ํ์ผ์ ์ถ๊ฐํ ์ ์๋ ํจ์๋ฅผ ์ ๊ณตํฉ๋๋ค. ํ์ด์ง ์์ฒญ์ด ์๋ฒ์ ๋๋ฌํ ๋๋ง๋ค ์คํ๋๋ ํจ์์ ๋๋ค. ๋น๋ ์๊ฐ์ด๋ ๋งค์ด๋ง๋ค ์ฌ์ ์์ฑํ์ง ์๊ณ ์๋ฒ์์๋ง ์๋ํ๋ ์ฝ๋์ฃ .
์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌํ ํ ์ ์ ๋๋ ๋ชจ๋ ์์ฒญ์ ๋ํด์๋ง ์ฌ์คํ๋ฉ๋๋ค. getServerSideProps์ ์ด ์ฝ๋๋ฅผ ์์ฑํ๋๋ฐ์. getStaticProps์ฒ๋ผ ์ด ์ญ์๋ ๋น๋๊ธฐ ํจ์์ ๋๋ค. ํ์ด์ง ์ปดํฌ๋ํธ ํ์ผ์๋ง ์ถ๊ฐํ ์ ์์ฃ . ํ์ง๋ง ํ์ด์ง ์ปดํฌ๋ํธ ํ์ผ์ ์ด๋ฐ ํจ์๊ฐ ์์ผ๋ฉด NextJS๊ฐ ํด๋น ํจ์๋ฅผ ์คํํฉ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์ฐ๋ฆฌ๊ฐ ๋ค๋ฃฌ getStaticProps ํจ์๋ getServerSideProps ํจ์ ์ค ํ๋๋ง ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ถฉ๋์ ์ผ์ผํค๋๊น์. ๋ ๋ค ์ปดํฌ๋ํธ์ ํ๋กํผํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์๋ก NextJS๊ฐ ํด๋น ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํ ์ ์์ง๋ง ์คํ๋๋ ์์ ์๋ ์ฐจ์ด๊ฐ ์์ต๋๋ค.
105. ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ "getServerSideProps" ์ฌ์ฉํ๊ธฐ
user-profile.js ํ์ผ์ ๋ง๋ค์ด๋ด ์๋ค.
export default function UserProfilePage(props) {
return <h1>{props.username}</h1>;
}
export async function getServerSideProps(context) {
return {
props: {
username: "Max",
},
};
}
์ฌ์ฉ์์ ๋ํ ๊ตฌ์ฒด์ ์ธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ํ๋ฉด์ ์ถ๋ ฅํ๋ ๊ฒ ๋ชฉ์ ์ด์ฃ . ์ด์ ์ฒ๋ผ export default๋ก ๋ด๋ณด๋ด์ค๋๋ค. ๋จ, ์ด ํ์ด์ง์๋ ์ฌ์ ๋ ๋๋ง์ ์ํํ ์ ์์ด์. ์ด๋ค ์ฌ์ฉ์๊ฐ ๋ ๋๋งํ๋์ง๋ฅผ ๋จผ์ ํ์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ด์ฃ . URL์ ํตํด ์ฌ์ฉ์ ID๋ฅผ ์ ์ถํ ์ ์์ผ๋ ์ด๋ฐ ์์ผ๋ก ๋์ ๋ผ์ฐํ ์ปดํฌ๋ํธ๋ฅผ ์์ฑํ ์ ์๊ฒ ์ฃ . ํ์ง๋ง ๊ทธ๋ด ๊ฒฝ์ฐ, ์ด ID๋ก ๋ธ๋ผ์ฐ์ ์ ์ ์ํ ์ฌ๋๋ค์ด ํด๋น ์ฌ์ฉ์์ ๋ํ ๋ฐ์ดํฐ์ ์ ๊ทผํ ์ ์๊ฒ ๋์ฃ . ์ฐ๋ฆฌ๊ฐ ์ํ๋ ์ํฉ์ ์๋์ฃ . ์ฐ๋ฆฌ๋ ์์ฒญ์ ๋ณด๋ธ ์ฌ์ฉ์๊ฐ ๋๊ตฐ์ง ํ์ธํ๋ ๊ฒ ๋ชฉ์ ์ ๋๋ค.
์ฌ๊ธฐ์ ์ค์ํ ๋ถ๋ถ์ ์ฟ ํค์ ํค๋๊ฐ ๋ ์์ฒญ ๊ฐ์ฒด์ ์ ๊ทผํด์ ์ด๋ ์ฌ์ฉ์๊ฐ ์์ฒญ์ ๋ณด๋๋์ง ์์๋ด๋ ๊ฒ๋๋ค. getServerSideProps์ ์ ํ์ ์ธ ์ฌ์ฉ ์ฌ๋ก์ฃ . ์ด๋ ์ฌ์ฉ์๊ฐ ์ ๊ทผํ๋์ง๋ ๋ชจ๋ฅด๊ณ ์ฟ ํค์๋ ์ ๊ทผํ ์ ์์ผ๋ฏ๋ก ์ด ํ์ด์ง์ ์ฌ์ ๋ ๋๋ง์ ์ํํ ์ ์์ด์. ๋ฐ๋ผ์ ๋น๋๊ธฐ ํจ์๋ฅผ ๋ด๋ณด๋ด์ผ(export) ํฉ๋๋ค. ๋ฐ๋ก getServerSideProps๋ผ๋ ๋น๋๊ธฐ ํจ์์ฃ . ๊ทธ๋ฆฌ๊ณ ์ฝํ ์คํธ(context)๋ผ๋ ๊ฐ์ฒด๋ฅผ ์ค์ ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ์ฒด ํ๋๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค. ์ด ๋ฐํํ ๊ฐ์ฒด๋ getStaticProps์ ๊ฐ์ ํฌ๋งท์ผ๋ก ์ค์ ํด์ผ ํ์ฃ . ๋ฐ๋ผ์ ๊ฐ์ฒด ๋ฐํํ๋ ๋ถ๋ถ์ ๋๊ฐ์์. props ํค๋ ํ์๊ณ , notFound ํค๋ ์์ด๋ ๋๊ณ ์์ด๋ ๋์ฃ . redirect ํค๋ ๋ง์ฐฌ๊ฐ์ง๊ณ ์ revalidate ํค๋ง ์ฃผ์ํ๋ฉด ๋ฉ๋๋ค. ์ด ํค๋ ํ์ํ์ง ์์๋ฟ๋๋ฌ ์ปดํฌ๋ํธ์ ์ค์ ํ ์๋ ์์ฃ . ์ ์ํ getServerSideProps ํจ์๋ง๋ค ๋ค์ด์ค๋ ์์ฒญ์ ์ ๋ถ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์คํํ๊ฑฐ๋ ์. ๋ฐ๋ผ์ ์ผ์ ์๊ฐ์ด ์ง๋๋ ์ ํจ์ฑ ์ฌ๊ฒ์ฌ๋ฅผ ์คํํ ํ์๊ฐ ์๋ ๊ฒ ํญ์ ์คํ๋๊ธฐ ๋๋ฌธ์ด์ฃ . ๋ฐ๋ผ์ props๋ฅผ ๊ฐ์ฒด๋ก ๋ด๋ณด๋ ๋๋ค. ํจ์ ์ด๋ฆ์ด getServerSideProps๋๊น ๋น์ฐํ ๊ฑฐ์ฃ . ๊ทธ๋ฆฌ๊ณ ์ด ํ๋กํผํฐ๋ ํจ์๋ก ์คํํ ์ ์๊ฒ ๋ฉ๋๋ค. ํจ์๋ฅผ ์คํํ๋ ์ฃผ์ฒด๋ ์ฌ์ ํ Next.js์ฃ . ํ์ง๋ง, ์์ ๋งํ๋ฏ์ด ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ธฐ ์ ์ ๋ถ๋ฌ์ค๋ ๊ฒ ์๋๋ผ ์์ฒญ์ด ๋ค์ด์ฌ ๋๋ง๋ค ๋ถ๋ฌ์ค๋ ๊ฑฐ์ฃ . ์ด์ username ํ๋กํผํฐ๋ฅผ ์ธ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ปดํฌ๋ํธ ํจ์์ props.username์ ์ถ๋ ฅํ๋ ๊ฑฐ์ฃ . ์ ์ฅํ ํ์ ์ฐ๋ฆฌ๊ฐ ๋ฐฉ๊ธ ์ถ๊ฐํ /user-profile ํ์ด์ง๋ก ์ด๋ํ๋ฉด Max๋ผ๋ ๊ธ์๊ฐ ํ์๋ ๊ฒ๋๋ค. ์ด์จ๋ getServerSideProps ํจ์๊ฐ ์ ์๋ํ๋ค๋ ๋ป์ด์ฃ .
ํ์ง๋ง ์ค์ํ ์ ์ด ์์ต๋๋ค. ์ด ํจ์๋ ๋ฐฐํฌ๋ ์๋ฒ์ ๊ฐ๋ฐ ์๋ฒ์์๋ง ์คํ๋๋ค๋ ์ ์ ๋๋ค. ํ์ง๋ง ์ฌ์ ์ ์์ฑ๋ ์ ์ ํจ์๋ ์๋์ฃ . ์ด๋ ์ฐ๋ฆฌ๊ฐ ์์์ผ ํ ์ค์ํ ์ ์ ์์ฌํฉ๋๋ค.
106. "getServerSideProps" ๊ณผ ์ฝํ ์คํธ
getServerSideProps ํจ์๊ฐ ์๋ฒ์์๋ง ์คํ๋๋ค๋ ๊ฒ ๋ฌด์จ ๋ง์ผ๊น์?
๊ทธ๊ฑด ๋ฐ๋ก ์ฝํ ์คํธ(context) ๊ฐ์ฒด๋ฅผ ๋ณด์๋ฉด ์ ์ ์์ต๋๋ค getStaticProps ํจ์์ context์ ๋ฌ๋ฆฌ ๋งค๊ฐ๋ณ์(params) ๊ฐ์ฒด๋ ๋ ์ค์ํ ๋ถ๋ถ์ ์ ๊ทผํ๋ ๊ฒ ๋์ด ์๋๋๋ค. ์์ฒญ(req) ๊ฐ์ฒด ์ ์ฒด์๋ ์ ๊ทผํ ์ ์๊ฒ ๋์ฃ . ์๋ต(res) ๊ฐ์ฒด์ ์ ๊ทผํด์ ํด๋น ์์ฒญ์ ์กฐ์ ํ๊ฑฐ๋ ํค๋๋ ์ถ๊ฐํ ์ ์๊ณ ์. ์ ํํ ๋งํ์๋ฉด, context ๊ฐ์ฒด์ ๋ ์ฌ๋ฌ ๊ฐ๊ณผ ํค๋ฅผ ์ป์ ์ ์๊ณ ๋งค๊ฐ๋ณ์ ๊ฐ์ฒด์๋ ์ฌ์ ํ ์ ๊ทผํ ์ ์๊ฒ ๋๋ ๊ฒ๋๋ค. ๋์ ์ปดํฌ๋ํธ ํ์ด์ง๊ฐ ์๋ ํ ๊ทธ ์ฌ์ค์ ๋ณํจ์์ฃ .
๋ฌผ๋ก ์ง๊ธ์ ์์ง๋ง ๋ง์ฝ ์ด๊ฒ ๋์ ์ปดํฌ๋ํธ ํ์ด์ง์๋ค๋ฉด params ๊ฐ์ฒด์๋ ์ฌ์ ํ ์ ๊ทผํ ์ ์์ฃ . ๋ค๋ง ์์ ๋งํ๋ฏ์ด ๊ทธ๊ฒ ๋์ด ์๋๋ผ ์์ฒญ ๊ฐ์ฒด์ ์๋ต ๊ฐ์ฒด์๋ ์ ๊ทผํ ์ ์๊ฒ ๋๋ ๊ฒ๋๋ค. Node.js, ํนํ Express.js์ ๊ดํด ์ด๋ ์ ๋ ์๋ ๋ถ์ด๋ผ๋ฉด ์ต์ํ ๊ฐ๋ ์ผ ๊ฒ๋๋ค ํด๋น ์ํํธ์จ์ด์์ ์๋ฒ ์ฌ์ด๋ ์ฝ๋๋ก ์์ฒญ ๊ฐ์ฒด์ ์๋ต ๊ฐ์ฒด๋ฅผ ๋ค๋ฃจ๊ธฐ๋ ํ๋๊น์. ๊ทธ๋ฆฌ๊ณ ์ ์ ํ ์๋ต์ ์ป์ ๋๊น์ง ํ์ํ ๋งํผ ์์ฒญ ๊ฐ์ฒด๋ฅผ ์กฐ์ข ํ ์๋ ์๊ณ ์. ์์ฒญ์ ๋ค์ ๋ณด๋ด๋ ๋ถ๋ถ์ ๊ฑฑ์ ํ์ง ์์๋ ๋ฉ๋๋ค. Next.js๊ฐ ๋์ ํด์ค ๊ฑฐ์์. ํ์ง๋ง ์์ฒญ์ด ๊ฐ๊ธฐ ์ ์ ์กฐ์ ํ๋ ๋ฐฉ๋ฒ๋ ์์ฃ ์๋ฅผ ๋ค์ด, ํค๋๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ฟ ํค๋ฅผ ์ถ๊ฐํ๋ ๊ฒ ๊ฐ์ด์. ๋ฟ๋ง ์๋๋ผ, ์๋ฒ์ ๋๋ฌํ ์์ฒญ ๊ฐ์ฒด๋ฅผ ๋ถ์ํด์ ๊ฑฐ๊ธฐ์ ๋ค์ด์ค๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์๋ ์์ต๋๋ค. ์ง๊ธ ๋ฐ์ ์์ฒญ ๊ฐ์ฒด์ ์๋ต ๊ฐ์ฒด๋ ๊ณต์ Node.js ๊ธฐ๋ณธ ์ ๋ ฅ ๋ฉ์์ง์ ์๋ต ๊ฐ์ฒด์ ๋๋ค. ์ฐ์ ์์ฒญ ๊ฐ์ฒด์ ์๋ต ๊ฐ์ฒด์ ๊ฐ๋จํ๊ฒ ์ฝ์ ๋ก๊ทธ๋ฅผ ์คํํด ์ฃผ๊ณ ์ด๋ป๊ฒ ๋๋์ง ์ดํด๋ณด๋๋ก ํฉ์๋ค.
์ ์ฅํ๊ณ ์ฌ์ฉ์ ํ๋กํ ํ์ด์ง๋ฅผ ์๋ก ๊ณ ์นจํ ๋ค์ ์ฝ๋๋ฅผ ๋ค์ ์คํํ๋ฉด ์ด๋ ๊ฒ ๊ธด ๋ก๊ทธ๊ฐ ๋ฐ ๊ฒ๋๋ค. ๋ ๊ฐ์ฒด์ ๋ด์ฅ๋ ๋ฉ์๋์ ํ๋กํผํฐ๊ฐ ์์ฒญ ๋ง๊ธฐ ๋๋ฌธ์ด์ฃ . ๊ทธ๋์ ์์ฒญ ๋ณต์กํ ๊ฑด๋ฐ ์ง๊ธ์ ์์ธํ ๋ค๋ฃจ์ง ์๊ฒ ์ต๋๋ค. ๋ค๋ง, ๊ฐ๋ น ํค๋๊ฐ ๋ค์ด์๋ค๋ฉด ํ์์ ์ถ์ถํ ์๋ ์์ต๋๋ค. ์ง๊ธ์ ํ์ ์์ง๋ง ๋์ค์ ์ธ์ฆ ์ ์ฐจ์ ๋ํ ๊ฐ์์์๋ ํ์ํ๊ฒ ๋ฉ๋๋ค. ๋ ๊ฐ์ฒด๋ Node.js ๊ธฐ๋ณธ ์ ๋ ฅ ๋ฉ์์ง์ ์๋ต์ ๋ํ ๊ฐ์ฒด์ ๋๋ค ์ด๋ฐ ํน์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ฒ ์ค์ํด์ง๋ ๋๊ฐ ์์ต๋๋ค. ์์ ๋งํ ํน์ ํค๋๋ ์ฟ ํค ๋ฐ์ดํฐ๊ฐ ํ์ํ ๋์ ๋๋ค.
107. ๋์ ํ์ด์ง & "getServerSideProps"
108. "getServerSideProps" ๋ด๋ถ์์ ์ผ์ด๋๊ณ ์๋ ์ผ
Route (pages) Size First Load JS
โ โ / (ISR: 10 Seconds) 2.84 kB 81.8 kB
โ /_app 0 B 78.9 kB
โ λ /[uid] 375 B 79.3 kB
โ โ /404 212 B 79.1 kB
โ โ /products/[pid] (664 ms) 470 B 79.4 kB
โ โ /products/p1
โ โ /products/p2
โ โ /products/p3
โ λ /user-profile 386 B 79.3 kB
+ First Load JS shared by all 79.1 kB
โ chunks/framework-0f397528c01bc177.js 45.7 kB
โ chunks/main-5cebf592faf0463a.js 31.8 kB
โ chunks/pages/_app-aba2de2b7ae6fcb3.js 390 B
โ chunks/webpack-2369ea09e775031e.js 1.02 kB
โ css/49861c0d8668ac82.css 185 B
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
โ (Static) automatically rendered as static HTML (uses no initial props)
โ (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
(ISR) incremental static regeneration (uses revalidate in getStaticProps)
โจ Done in 6.95s.
โ nextjs-pre-rendering git:(main) โ yarn run dev
yarn run v1.22.17
$ next dev
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
event - compiled client and server successfully in 412 ms (154 modules)
wait - compiling / (client and server)...
event - compiled client and server successfully in 175 ms (209 modules)
(Re-) Generating...
wait - compiling /user-profile (client and server)...
event - compiled client and server successfully in 149 ms (212 modules)
Server side code
consol.log ๋ฌธ์ฅ์ ์ถ๊ฐํด์ ์ด ํจ์๊ฐ ์คํ๋ ๋ Server side code๋ผ๋ ํ ์คํธ๊ฐ ๋ก๊น ๋๋๋ก ํฉ์๋ค. ํ์ผ์ ์ ์ฅํ ๋ค run npm build ๋ช ๋ น์ด๋ก ์ด ํ๋ก๋์ ๋น๋๋ฅผ ์คํํ๋ฉด ์ธ์ ์ฝ๋๊ฐ ์คํ๋์๋์ง๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ํฐ๋ฏธ๋ ์์ญ์ ์ข ๋ ํค์์ ์ ๋ณด์ด๊ฒ ํ๊ณ ์. ํ์ด์ง๋ฅผ ์ฌ์ ์์ฑ(Pre-generate)ํ๋ค๋ ๋ก๊ทธ๊ฐ ๋ณด์ด๋๋ฐ ์ฌ๊ธฐ์ ์ฃผ๋ชฉํ ์ ์ ์ด์ ๊ณผ ๋๊ฐ์ ์์ ํ์ด์ง๊ฐ ์์ฑ๋๋ค๋ ๊ฒ๋๋ค. ์ฌ๋์(/) ๋ค์ ์๋ฌด๊ฒ๋ ์์ ๋๋ ์ฌ๊ฒ์ฆ(Revalidation)์ ๊ฑฐ์น ์ด๊ธฐ ํ์ด์ง๊ฐ ์๊ณ ๊ทธ๋ฆฌ๊ณ 404 ์ค๋ฅ ์ฝ๋ ํ์ด์ง์ P1, P2, P3 ์ ํ์ ๋ํ ์ ํ ํ์ด์ง๋ ์์ฑ๋์์ต๋๋ค. ์ฌ์ฉ์ ํ๋กํ ํ์ด์ง๊ฐ ์๋ ์ด์ ๋ ๋๋ค(Lambda) ๊ธฐํธ๋ก ์๋ ์๊ทธ๋(End signal)์ ํ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก [uid].js ํ์ผ๋ ์์ฑ๋์ง ์์์ฃ . ๋๋ค ๊ธฐํธ๊ฐ ์๋ ํ์ด์ง๋ค์ ์ฌ์ ์์ฑํ์ง ์๊ณ ์๋ฒ ์ธก์์๋ง ์ฌ์ ๋ ๋๋ง๋๋ค๋ ๋ป์ ๋๋ค.
user-profile์์ getServerSideProps๋ฅผ ๊ทธ๋ฆฌ๊ณ [uid].js์์๋ getServerSideProps๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ํด๋น ํ์ด์ง๊ฐ ์ฌ์ ์์ฑ๋์ง ์์ ๊ฒ์ ๋๋ค. ์ฌ๊ธฐ๊น์ง ๋ง์น๊ณ ๋ค์ npm start ๋ช ๋ น์ด๋ฅผ ์คํํ ๋ค localhost:3000๋ฅผ ๋ถ๋ฌ์ค๋ฉด ์ด๋ฐ ํ์ด์ง๊ฐ ๋์ค๊ณ ๋ค์ /user-profile์ ๋ถ์ด๋ฉด Max๋ผ๋ ํ ์คํธ๊ฐ ์ถ๋ ฅ๋ฉ๋๋ค. ์ฌ๊ธฐ์ npm start๋ก ํ๋ก๋์ ์๋ฒ๋ฅผ ์คํํ ํฐ๋ฏธ๋์ ํ์ธํด ๋ณด๋ฉด Server side code๋ผ๋ ํ ์คํธ๊ฐ ๋ก๊น ๋ ๊ฒ์ ํ์ธํ ์ ์์ฃ . ์์ consol.log ๊ฐ์ฒด(Object)์ ์ถ๋ ฅ๊ฐ์ด ๋์์ผ๋ ์ด ์ฝ๋๊ฐ ์คํ๋๋ค๋ ๊ฒ์ ์ ์ ์์ง๋ง ์์ ๋ณด์ฌ๋๋ฆฐ ๊ฒ์ฒ๋ผ ์ด ํ์ด์ง๋ ์ฌ์ ์์ฑ๋์ง ์์์ต๋๋ค.
์ปดํฌ๋ํธ(Component)์ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ์์ ๋ฏธ๋ฆฌ ์ค๋นํด์ ํด๋ผ์ด์ธํธ์๊ฒ ์์ฑ๋ ํ์ด์ง๋ฅผ ์ ๊ณตํ๋ฉด ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ ์ ์๊ณ ์ฌ์ฉ์๋ค์ ์ฒ์๋ถํฐ ์์ฑ๋ ํ์ด์ง์์ ๋ชจ๋ ์ฝํ ์ธ ๋ฅผ ์ด์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค. ๊ทธ ์ธ์๋ ๊ฒ์ ์์ง ํฌ๋กค๋ฌ๊ฐ ์์ฑ๋ ํ์ด์ง๋ฅผ ํ์ธํด์ ๊ฒ์ ์์ง ์ต์ ํ์๋ ๋์์ด ๋ ๊ฒ์ ๋๋ค.
109. ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ฐ์ดํฐ fetching ์ ๊ฐ์ (์ธ์ ์ฌ์ฉํด์ผ ํ ๊น?)
110. ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ฐ์ดํฐ fetching ๊ตฌํํ๊ธฐ
firebase์ ์ ์ > Realtime Database๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
111. useSWR ์ฐธ๊ณ ์ฌํญ
useSWR๋ก ์์ ์ ํ ๋๋, ๊ธฐ๋ณธ “fetcher”๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
- useSWR(<request-url>, (url) => fetch(url).then(res => res.json()
112. useSWR NextJS ํ ์ฌ์ฉํ๊ธฐ
https://www.udemy.com/course/nextjs-react-incl-two-paths/