Data Fetching
•
•
async및 await 서버 구성 요소에서 데이터를 가져오는 데 사용할 수 있다
async function getData() {
const res = await fetch('https://api.example.com/...')
// The return value is *not* serialized
// You can return Date, Map, Set, etc.
// Recommendation: handle errors
if (!res.ok) {
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data')
}
return res.json()
}
export default async function Page() {
const data = await getData()
return <main></main>
}
TypeScript
복사
•
기본 : fetch는 무기한으로 데이터를 자동으로 가져오고 캐시한다.
fetch('https://...') // cache: 'force-cache' is the default
TypeScript
복사
데이터 재검증
•
시간 간격으로 캐시된 데이터의 유효성 재검사를 하려면 next.revalidate 옵션을 사용하여 cache 리소스 수명을 설정할 수 있다.
fetch('https://...', { next: { revalidate: 10 } })
TypeScript
복사
•
모든 요청에서 최신 데이터를 가져오려면 cache: ‘no-store’옵션 사용
fetch('https://...', { cache: 'no-store' })
TypeScript
복사
병렬 데이터 가져오기
•
waterfall과 반대되는 병렬 접근 방식
import Albums from './albums'
async function getArtist(username: string) {
const res = await fetch(`https://api.example.com/artist/${username}`)
return res.json()
}
async function getArtistAlbums(username: string) {
const res = await fetch(`https://api.example.com/artist/${username}/albums`)
return res.json()
}
export default async function Page({
params: { username },
}: {
params: { username: string }
}) {
// Initiate both requests in parallel
const artistData = getArtist(username)
const albumsData = getArtistAlbums(username)
// Wait for the promises to resolve
const [artist, albums] = await Promise.all([artistData, albumsData])
return (
<>
<h1>{artist.name}</h1>
<Albums list={albums}></Albums>
</>
)
}
TypeScript
복사
•
import { getArtist, getArtistAlbums, type Album } from './api'
export default async function Page({
params: { username },
}: {
params: { username: string }
}) {
// Initiate both requests in parallel
const artistData = getArtist(username)
const albumData = getArtistAlbums(username)
// Wait for the artist's promise to resolve first
const artist = await artistData
return (
<>
<h1>{artist.name}</h1>
{/* Send the artist information first,
and wrap albums in a suspense boundary */}
<Suspense fallback={<div>Loading...</div>}>
<Albums promise={albumData} />
</Suspense>
</>
)
}
// Albums Component
async function Albums({ promise }: { promise: Promise<Album[]> }) {
// Wait for the albums promise to resolve
const albums = await promise
return (
<ul>
{albums.map((album) => (
<li key={album.id}>{album.name}</li>
))}
</ul>
)
}
TypeScript
복사
순차적 데이터 가져오기
•
데이터
// ...
async function Playlists({ artistID }: { artistID: string }) {
// Wait for the playlists
const playlists = await getArtistPlaylists(artistID)
return (
<ul>
{playlists.map((playlist) => (
<li key={playlist.id}>{playlist.name}</li>
))}
</ul>
)
}
export default async function Page({
params: { username },
}: {
params: { username: string }
}) {
// Wait for the artist
const artist = await getArtist(username)
return (
<>
<h1>{artist.name}</h1>
<Suspense fallback={<div>Loading...</div>}>
<Playlists artistID={artist.id} />
</Suspense>
</>
)
}
TypeScript
복사