Data Fetching[Next.js]

SnowCat·2023년 4월 25일
0

Next.js

목록 보기
13/16
post-thumbnail

Server Component에서의 async함수 사용

  • React RFC를 사용해 서버 컴포넌트에서 데이터를 가져올 수 있음
async function getData() {
  const res = await fetch('https://api.example.com/...');

  // 에러 핸들링
  if (!res.ok) {
    throw new Error('Failed to fetch data');
  }

  return res.json();
}

export default async function Page() {
  const data = await getData();
	
  // 타입스크립트에서 타입에러 발생시 다음과 같은 주석 작성 필요
  return <main>
  {/* @ts-expect-error Async Server Component */}
  </main>;
}
  • 서버에서 데이터를 가져올 때 cookies(), headers()를 통해 추가적인 정보를 읽어낼 수 있음

Data Fetching

  • 정적인 데이터를 패칭할 경우 기본적으로 패칭된 데이터는 캐싱됨
  • 일정한 시간간격으로 데이터 재검증이 필요하거나, 캐싱이 불필요한 경우, fetch 메서드에 revalidate 옵션을 주어야 함
fetch('https://...', { next: { revalidate: 10 } });
fetch('https://...', { cache: 'no-store' });

Data Fetching Patterns

  • 일반적으로 Promise.all을 사용해 여러 데이터를 동시에 가져오는 Parallel Data Fetching을 사용함
    모든 데이터를 받아올 때 까지 렌더링된 화면을 보지 못하기 때문에 suspense boundary를 사용해 데이터 패칭시 화면을 설정해주는것이 좋음
import Albums from './albums';

async function getArtist(username) {
  const res = await fetch(`https://api.example.com/artist/${username}`);
  return res.json();
}

async function getArtistAlbums(username) {
  const res = await fetch(`https://api.example.com/artist/${username}/albums`);
  return res.json();
}


export default async function Page({ params: { username } }) {
  // 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>
    </>
  );
}
  • 하나씩 순차적으로 데이터를 가져올수도 있으며, 이 때는 fetch내부에서 await을 사용하거나, 여러개의 fetch 함수를 순차적으로 실행시켜서 구현함
async function Playlists({ artistID }) {
  // 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 } }) {
  // Wait for the artist
  const artist = await getArtist(username);

  return (
    <>
      <h1>{artist.name}</h1>
      <Suspense fallback={<div>Loading...</div>}>
        <Playlists artistID={artist.id} />
      </Suspense>
    </>
  );
}

Blocking Rendering in a Route

  • 레이아웃에서 데이터를 패칭하게 되면, 세그먼트 밑에 있는 모든 렌더링은 데이터 로딩이 끝나야만 진행되게 됨
  • 로딩 중 화면을 표시하기 위해서는 loading.js를 사용하거나, 데이터 페칭을 하위 세그먼트로 이동해 레이아웃이 출력되지 않는 부분을 최소화 시켜줘야 함

fetch()없이 데이터 가져오기

  • 타사 라이브러리나 ORM등을 사용해 fetch 메서드를 사용하지 않는 경우가 있음
  • 이 때도 서버측에서 데이터를 가져올 수 있지만, 캐싱 동작이 fetch만을 사용할때와는 달라지게 됨
    routing시의 캐싱에 영향을 받지 않게되고 캐싱 여부는 경로 세그먼트의 동/정적 여부로 갈리게 됨

출처:
https://beta.nextjs.org/docs/data-fetching/fetching

profile
냐아아아아아아아아앙

0개의 댓글