1. 데이터를 가져오는 기본 방법
1.1 서버에서 fetch API로 가져오기
export default async function Page() {
const data = await fetch('<https://api.vercel.app/blog>')
const posts = await data.json()
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
- Next.js 15부터 기본적으로 캐시되지 않음 (
cache: no-store
)
- 이전 버전에서는 기본값이
cache: force-cache
였음
- 정적 페이지로 미리 만들어질 수 있음
export const dynamic = 'force-dynamic'
을 추가하면 항상 동적으로 동작
1.2 데이터베이스에서 직접 가져오기
import { db, posts } from '@/lib/db'
export default async function Page() {
const allPosts = await db.select().from(posts)
return (
<ul>
{allPosts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
- 기본적으로 캐시되지 않음
- unstable_cache로 캐싱 가능
- 쿠키나 헤더, searchParams를 사용하면 자동으로 동적 렌더링됨
2. 효율적인 데이터 페칭 패턴
2.1 컴포넌트 외부에 함수 선언하기
// 컴포넌트 파일 최상단에 함수 선언
async function getArtist(username: string) {
const res = await fetch(`https://api.example.com/artist/${username}`)
return res.json()
}
async function getAlbums(username: string) {
const res = await fetch(`https://api.example.com/artist/${username}/albums`)
return res.json()
}
// 컴포넌트에서 사용
export default async function Page({ params }) {
const { username } = await params
const artistData = getArtist(username) // 요청 시작
const albumsData = getAlbums(username) // 병렬로 요청 시작
const [artist, albums] = await Promise.all([artistData, albumsData])
return (
<>
<h1>{artist.name}</h1>
<Albums list={albums} />
</>
)
}
- 함수를 외부에 선언하여 코드 구조화
- 여러 컴포넌트에서 재사용 가능
- 병렬 데이터 페칭을 더 쉽게 구현 가능
- 함수를 컴포넌트 외부에 선언하면, 컴포넌트 내부에서 동시에 여러 함수를 호출하여 병렬로 데이터를 페칭할 수 있습니다. 예를 들어, Promise.all을 사용하여 두 요청을 동시에 시작함으로써 전체 로딩 시간을 단축할 수 있습니다.
- 그러나, 병렬 데이터 페칭으로 소요되는 로딩 시간은 가장 오래 걸리는 fetching 시간 만큼입니다.