ํฐ์คํ ๋ฆฌ ๋ทฐ
๐ก Next.js App Router ๋ฐ์ดํฐ ํจ์นญ ์๋ฒฝ ๊ฐ์ด๋
octo54 2025. 4. 17. 11:04๐ก Next.js App Router ๋ฐ์ดํฐ ํจ์นญ ์๋ฒฝ ๊ฐ์ด๋
Next.js App Router๋ ์๋ฒ/ํด๋ผ์ด์ธํธ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฐํ๊ฒ ํจ์นญํ ์ ์๋๋ก ๋ค์ํ ๋ฐฉ์์ ์ ๊ณตํฉ๋๋ค. ์ด ๊ธ์์๋ ์๋ฒ ์ปดํฌ๋ํธ ๊ธฐ๋ฐ fetch, ํด๋ผ์ด์ธํธ ์ํ ๊ธฐ๋ฐ ์์ฒญ, ๊ทธ๋ฆฌ๊ณ ๋ก๋ฉ ๊ด๋ฆฌ๊น์ง ์ ๋ฐ์ ์ธ ์ฌ์ฉ๋ฒ์ ์ ๋ฆฌํฉ๋๋ค.
โ ์๋ฒ ์ปดํฌ๋ํธ์์์ ๋ฐ์ดํฐ ํจ์นญ
Next.js App Router์์๋ ํ์ด์ง์ ๋ ์ด์์์ด ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฒ ์ปดํฌ๋ํธ์ ๋๋ค. ์๋ฒ์์ ์ง์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ด ๊ธฐ๋ณธ ๊ตฌ์กฐ์ ๋๋ค.
๐น fetch ์ฌ์ฉ ์์
// app/posts/page.tsx
export default async function Page() {
const res = await fetch('https://api.example.com/posts', {
cache: 'no-store', // ๋๋ next: { revalidate: 60 }
});
const posts = await res.json();
return (
{posts.map((post) => (- {post.title}
))}
);
}
- cache: 'no-store': ๋งค ์์ฒญ๋ง๋ค ์๋ก ๊ฐ์ ธ์ด
- next: { revalidate: 60 }: 60์ด ๊ฐ ์บ์๋ ๋ฐ์ดํฐ ์ฌ์ฉ (ISR)
โ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์์์ ๋ฐ์ดํฐ ํจ์นญ
ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ('use client')๋ useEffect, fetch, SWR ๋ฑ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
๐น ํด๋ผ์ด์ธํธ fetch + useEffect
'use client';
import { useEffect, useState } from 'react';
export default function ClientPosts() {
const [posts, setPosts] = useState([]);
useEffect(() => {
fetch('/api/posts')
.then(res => res.json())
.then(data => setPosts(data));
}, []);
return (
<ul>
{posts.map((p) => (
<li key={p.id}>{p.title}</li>
))}
</ul>
);
}
๐น SWR ์ฌ์ฉ (๋น๋๊ธฐ ์บ์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ)
'use client';
import useSWR from 'swr';
const fetcher = url => fetch(url).then(res => res.json());
export default function Profile() {
const { data, error, isLoading } = useSWR('/api/profile', fetcher);
if (isLoading) return <div>๋ก๋ฉ ์ค...</div>;
if (error) return <div>์๋ฌ ๋ฐ์</div>;
return <h1>{data.name}</h1>;
}
- ์๋ ์บ์ฑ ๋ฐ ์ฌ๊ฒ์ฆ ์ง์
- ์ ์ญ ์ํ ๊ณต์ ๊ฐ๋ฅ
โ ๋ฐ์ดํฐ ๋ก๋ฉ UX ๊ฐ์
App Router๋ ๋ก๋ฉ ์ํ ์ ์ฉ ์ปดํฌ๋ํธ์ Suspense๋ฅผ ํจ๊ป ์ฌ์ฉํด ๋ฐ์ดํฐ ๋ก๋ฉ ์ UX๋ฅผ ๊ฐ์ ํ ์ ์์ต๋๋ค.
๐น loading.tsx ์ฌ์ฉ
// app/posts/loading.tsx
export default function Loading() {
return <p>๊ฒ์๊ธ ๋ถ๋ฌ์ค๋ ์ค...</p>;
}
ํด๋น ๋๋ ํ ๋ฆฌ์ page.tsx๊ฐ ๋ก๋ฉ๋ ๋ ์๋์ผ๋ก ํ์๋ฉ๋๋ค.
๐น Suspense๋ก ๋น๋๊ธฐ ์ปดํฌ๋ํธ ๊ฐ์ธ๊ธฐ
// app/posts/page.tsx
import { Suspense } from 'react';
import PostList from './PostList';
export default function Page() {
return (
<Suspense fallback={<p>๋ถ๋ฌ์ค๋ ์ค...</p>}>
<PostList />
</Suspense>
);
}
PostList๊ฐ async ์ปดํฌ๋ํธ๋ผ๋ฉด Suspense๋ก ๊ฐ์ธ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
โ ์ค๋ฌด ํจํด ์์ฝ
ํจ์นญ ์์น ์ฌ์ฉ ๋ฐฉ์ ๊ถ์ฅ ์ํฉ
์๋ฒ ์ปดํฌ๋ํธ | fetch, DB ์ฟผ๋ฆฌ | ๋ณด์ ๋ฐ์ดํฐ, ์ด๊ธฐ ํ์ด์ง ๋ ๋๋ง |
---|---|---|
ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ | useEffect + fetch | ์ฌ์ฉ์ ์ํธ์์ฉ, ๋น๋๊ธฐ UI |
ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ | SWR / React Query | ์บ์ฑ, ์ ์ญ ๊ณต์ , ์๋ ๊ฐฑ์ |
์๋ฒ ์ปดํฌ๋ํธ | revalidate ์ต์ | ์ฃผ๊ธฐ์ ISR ์ฌ์ฉ ์ |
โ ๊ฒฐ๋ก
- ์๋ฒ ์ปดํฌ๋ํธ = ์์ ํ๊ณ ๋น ๋ฅธ ์ด๊ธฐ ๋ฐ์ดํฐ ๋ ๋๋ง
- ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ = ์ฌ์ฉ์ ์ํธ์์ฉ ์ค์ฌ ์ฒ๋ฆฌ
- SWR = ํด๋ผ์ด์ธํธ ์บ์ฑ ์ต์ ํ
- loading.tsx + Suspense = ๋ถ๋๋ฌ์ด UX ์ ๊ณต
Next.js App Router๋ ๋ฐ์ดํฐ ํจ์นญ ๊ตฌ์กฐ๊ฐ ๋งค์ฐ ์ ์ฐํฉ๋๋ค. ์๋ฒ ๊ธฐ๋ฐ์ผ๋ก ๊ธฐ๋ณธ ๋์ํ๋, ํด๋ผ์ด์ธํธ ์ ํ๋ ์ฌ์ฐ๋ฏ๋ก ์ํฉ์ ๋ง์ถฐ ์กฐํฉํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
Next.js, App Router, ๋ฐ์ดํฐ ํจ์นญ, ์๋ฒ ์ปดํฌ๋ํธ, ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ, fetch, SWR, React Query, Suspense, UX ์ต์ ํ
'framework > NextJS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
- Total
- Today
- Yesterday
- ๋ฅ๋ฌ๋
- ํ๋ก ํธ์๋๋ฉด์
- SEO ์ต์ ํ
- Python
- kotlin
- REACT
- Prisma
- ํ์ด์ฌ ์๊ณ ๋ฆฌ์ฆ
- CI/CD
- nextJS
- JAX
- Next.js
- seo ์ต์ ํ 10๊ฐ
- App Router
- ์น๊ฐ๋ฐ
- nodejs
- Ktor
- rag
- Webpack
- SEO์ต์ ํ
- fastapi
- gatsbyjs
- ๊ฐ๋ฐ๋ธ๋ก๊ทธ
- ํ๋ก ํธ์๋
- Docker
- PostgreSQL
- NestJS
- ๋ฐฑ์๋๊ฐ๋ฐ
- AI์ฑ๋ด
- llm
์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |