๊ฐ์ธ์ ํ์ต ๋ด์ฉ ๊ธฐ๋ก ์ค, ๊ทนํ ์ผ๋ถ์ ๋ด์ฉ๋ง ์์ฑ๋์์ต๋๋ค.
React VS Next
๋ฆฌ์กํธ : CSR (ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ ๋๋ง) - ๋ฒ๋ค
์ ์ pc์์ js์ html์ ๊ทธ๋ ค์ค
- ๊ฒ์์์ง(SEO)์ ์๊ฑธ๋ฆผ
- ์ฒซ ๋ก๋ฉ์ ์ง์ฐ ๋ฐ์
๋ฅ์คํธ : SSR (์๋ฒ์ฌ์ด๋ ๋ ๋๋ง) - ๋ฆฌ์กํธ ์ ์ํ๊ณ , html์ ๋ด๋ ค์ค
- ๊ฒ์์์ง์ ๋์ด
- ์ง์ฐ์ด ๋ฐ์๋์ง ์์
- fetch ํจ์ ์ต์ ํ, ๋ชจ๋ ๊ธฐ๋ฅ ์ต์ ํ ์ ๊ณต
- ๋ณ๋์ ๋ผ์ฐํฐ ์ค์ ์ด ํ์ ์๊ณ , ํ์ผ์์คํ ๊ธฐ๋ฐ ๋ผ์ฐํ ์ ๊ณต
SSR ์ฅ์ : ๋ณด์์ฑ, ํธํ์ฑ, SEO ์ต์ ํ
๋จ์ : ๋ ๋ง์ ์์ ์๋ชจ, ๋ง์ ๋ถํ, ์ ์ง๋ณด์ ๋น์ฉ ์ฆ๊ฐ, ํ์ด์ง ์์ฒญ ์๊ฐ ์ฆ๊ฐ, ๋ธ๋ผ์ฐ์ ์ ์ฉ API ์ฌ์ฉ ์ ๋ช ์์ ์ง์ ํ์
๐ ์์
์๋ฒ ์ปดํฌ๋ํธ (app/page.tsx)
// ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฒ ์ปดํฌ๋ํธ
export default async function Home() {
const data = await fetch('<https://api.example.com/data>')
const result = await data.json()
return <div>{result.title}</div>
}
ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ (components/Button.tsx)
'use client'
import { useState } from 'react'
export default function Button() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>ํด๋ฆญ {count}</button>
}
Next.js ํ๋ก์ ํธ ํ
1. ํ๋จ ๋ค๋น ๋ฒํผ ์์ ๊ธฐ : globals.css ์์
nextjs-portal { display: none; }
2. Next.js์์ ํด๋ ์ด๋ฆ์ ๋๊ดํธ([])๋ก ๊ฐ์ธ๋ฉด ๋์ ๋ผ์ฐํ (dynamic routing)์ด ์ ์ฉ
์๋ฅผ ๋ค์ด,
pages/products/[id].js
ํ์ผ์ด ์๋ค๋ฉด,
์ด๊ฑด /products/123, /products/abc ๊ฐ์ ๊ฒฝ๋ก๋ฅผ ๋์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ค๋ ๋ป
next js ์๋ฌ ํ์ด์ง / ๋ก๋ฉ ํ์ด์ง
๋ง๋ค๊ธฐ๋ง ํ๋ฉด ์์์ ์ ์ฉ๋๋ค.
์๋์ผ๋ก ์ ์ฉ๋๋ ์ด์ ⇒ Next.js์ ํ์ผ ์์คํ ๊ธฐ๋ฐ ๋ผ์ฐํ ๊ณผ ์๋ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ๋ก๋ฉ ์ํ ๊ด๋ฆฌ ๋๋ฌธ
- app/ ๋๋ ํ ๋ฆฌ ๋ด์ error.tsx ํ์ผ์ ์ถ๊ฐํ๋ฉด, Next.js๋ ์ฑ์ ๋ชจ๋ ํ์ด์ง์์ ๋ฐ์ํ ์ค๋ฅ๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌ
- ์๋ ์ ์ฉ: ์ด ํ์ผ์ด ์๋ ๋๋ ํ ๋ฆฌ์์ ๋ฐ์ํ ์์ธ๋ ์ค๋ฅ๋ฅผ ์๋์ผ๋ก ์บ์นํ๊ณ , ์ฌ์ฉ์๊ฐ ์ ์ํ ์๋ฌ UI๋ฅผ ๋ ๋๋งํจ.
- app/ ๋๋ ํ ๋ฆฌ ๋ด์ loading.tsx ํ์ผ์ ์ถ๊ฐํ๋ฉด, Next.js๋ ํด๋น ๋๋ ํ ๋ฆฌ์์ ์ปดํฌ๋ํธ๊ฐ ๋ก๋ฉ ์ค์ผ ๋ ์๋์ผ๋ก ๋ก๋ฉ UI๋ฅผ ํ์
- ์๋ ์ ์ฉ: ์ด ํ์ผ์ ํ์ด์ง๋ ์ปดํฌ๋ํธ๊ฐ ๋น๋๊ธฐ์ ์ผ๋ก ๋ก๋๋ ๋ ๋ก๋ฉ ์ํ๋ฅผ ์๋์ผ๋ก ํ์
์๋ฆฌ: React Suspense + ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)
Next.js๋ React์ Suspense ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(SSR)์ ํตํด ์ปดํฌ๋ํธ๋ฅผ ์๋ฒ์์ ๋ฏธ๋ฆฌ ๋ ๋๋งํ์ฌ ํ์ด์ง๋ฅผ ๋น ๋ฅด๊ฒ ๋ก๋ํจ
- loading.tsx๋ React Suspense๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ก๋ฉํ๋ ๋์ ํ์๋๋ ์ปดํฌ๋ํธ
- error.tsx๋ try-catch๋ ์ค๋ฅ ๋ฐ์ ์ React์ ์ค๋ฅ ๊ฒฝ๊ณ๋ฅผ ํ์ฉํ์ฌ ์๋ฌ๊ฐ ๋ฐ์ํ ๋ถ๋ถ์ ์บก์ฒํ๊ณ ๋์ฒด UI๋ฅผ ์ ๊ณต
Next.js์ fetch ์บ์ฑ ์ ๋ต
- ๊ธฐ๋ณธ ๋์:
- fetch๋ ๊ธฐ๋ณธ์ ์ผ๋ก force-cache๋ก ๋์ → ๊ฐ์ ์์ฒญ์ด๋ฉด ์บ์ ์ฌ์ฌ์ฉ (๋น๋ ์/๋ฐํ์ ๋ชจ๋).
- ํด๋ผ์ด์ธํธ ์ฌ์ด๋๋ ์บ์ฑ๋์ง๋ง, ๊ฐฑ์ ํ๋ ค๋ฉด ์ค์ ํ์.
- cache ์ต์
:
- force-cache: ์บ์๋ ๋ฐ์ดํฐ ์ฌ์ฉ (๊ธฐ๋ณธ๊ฐ).
- no-store: ํญ์ ์ ๋ฐ์ดํฐ ์์ฒญ (์ค์๊ฐ ๋ฐ์ดํฐ์ ์ ํฉ).
- ์ฌ๊ฒ์ฆ (ISR):
- next: { revalidate: ์ด } → ์ฃผ๊ธฐ์ ์ผ๋ก ์บ์ ๊ฐฑ์ .
- ๋์ ๋ฐ์ดํฐ:
- ๋์ URL๋ ๊ฐ๊ฐ ์บ์ฑ๋จ.
- ์ค์๊ฐ์ฑ ํ์ํ๋ฉด no-store ์ฌ์ฉ.
- ํด๋ผ์ด์ธํธ ์ฌ์ด๋:
- useSWR ๋ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์บ์ฑ/๊ฐฑ์ ์ธ๋ฐ ์ ์ด ๊ฐ๋ฅ.
- ์ฃผ์์ฌํญ:
- GET๋ง ์บ์ฑ๋จ, dev ๋ชจ๋์์๋ ์บ์ฑ X.
- URL/ํค๋/์ฟผ๋ฆฌ ๊ฐ์์ผ ์บ์ ์ฌ์ฌ์ฉ.