Next.js 앱 라우터는 React와 Web 플랫폼을 기반으로 한 새로운, 간소화된 데이터 패칭 시스템을 소개한다. 이 페이지에서는 데이터의 라이프사이클을 관리하는 데 도움이 되는 기본 개념과 패턴을 살펴볼 것이다.
다음은 이 페이지에서의 권장 사항에 대한 간략한 개요다
이 새로운 데이터 패칭 시스템은 기본 fetch()
Web API를 기반으로 구축되며, Server Components에서 async
와 await
을 사용한다.
fetch
를 확장하여 자동으로 요청 중복을 제거한다.fetch
옵션 객체를 확장하여 각 요청이 자체적인 캐싱 및 재유효화 규칙을 설정할 수 있게 합니다.가능한 경우, Server Components
에서 데이터를 패치하는 것을 권장한다. Server Components는 항상 서버에서 데이터를 패치한다.
이를 통해 다음과 같은 이점을 얻을 수 있다.
백엔드 데이터 리소스(예: 데이터베이스)에 직접적으로 접근할 수 있다.
액세스 토큰 및 API 키와 같은 민감한 정보가 클라이언트에 노출되지 않도록하여 응용 프로그램을 더 안전하게 유지할 수 있다.
데이터를 패치하고 동일한 환경에서 렌더링할 수 있다. 이는 클라이언트와 서버 간의 왕복 통신 및 클라이언트의 주 스레드 작업을 감소시킨다.
단일 라운드트립으로 여러 데이터 패치를 수행할 수 있으며 개별적인 다중 요청 대신 사용할 수 있다.
클라이언트-서버 간의 워터폴을 줄일 수 있다.
지역에 따라 데이터 패치가 데이터 소스에 더 가까이 발생하여 지연 시간이 감소하고 성능이 향상될 수도 있다
💡 알아두면 좋은점
데이터를 클라이언트 측에서 패치하는 것도 가능하다. SWR
또는 React Query
와 같은 타사 라이브러리를 사용하여 Client Components와 함께 사용하는 것을 권장한다. 미래에는 React의 use()
훅을 사용하여 Client Components에서도 데이터를 패치할 수 있게 될 것이다.
App Router에서는 레이아웃
, 페이지
및 컴포넌트 내에서 데이터를 패치할 수 있다. 데이터 패치는 Streaming
과 Suspense
와도 호환된다.
💡 알아두면 좋은점
레이아웃의 경우 부모 레이아웃과 그 하위 컴포넌트 간에 데이터를 전달하는 것은 불가능하다.
같은 데이터를 라우트 내에서 여러 번 요청하더라도, 해당 데이터가 필요한 레이아웃 내에서 직접 데이터를 패치하는 것을 권장한다.
React와 Next.js는 내부적으로 요청을 캐시하고 중복 제거하여 동일한 데이터가 여러 번 패치되는 것을 방지한다.
컴포넌트 내에서 데이터를 패치할 때에는 두 가지 데이터 패치 패턴을 고려해야 한다. 병렬 (Parallel)
과 순차 (Sequential)
패턴이다.
병렬 데이터 패치에서는 라우트 내의 요청이 즉시 시작되어 데이터를 동시에 로드한다다. 이를 통해 클라이언트 - 서버 간의 워터폴 현상과 데이터 로딩에 소요되는 총 시간을 줄일 수 있다.
순차 데이터 패치에서는 라우트 내의 요청이 서로 종속되어 워터폴을 만든다. 한 패치가 다른 패치의 결과에 의존하거나, 다음 패치 이전에 조건을 충족시키기를 원하는 경우가 있을 수 있다. 하지만 이러한 동작은 의도치 않게 발생할 수도 있으며, 로딩 시간이 더 오래 걸릴 수 있다.
만약 트리 내에서 여러 컴포넌트에서 동일한 데이터(예: 현재 사용자)를 패치해야 하는 경우, Next.js는 동일한 입력을 갖는 fetch
요청(GET
)을 자동으로 임시 캐시에 저장한다. 이 최적화는 렌더링 과정에서 동일한 데이터가 여러 번 패치되는 것을 방지한다.
서버에서는 캐시가 서버 요청의 수명 동안 유지되며, 렌더링 프로세스가 완료될 때까지 유지된다.
이 최적화는 레이아웃, 페이지, 서버 컴포넌트, generateMetadata
및 generateStaticParams
에서 수행되는 fetch
요청에 적용된다.
이 최적화는 정적 생성(static generation) 중에도 적용된다.
클라이언트에서는 캐시가 세션의 수명 동안 유지되며(여러 클라이언트 측 재렌더링을 포함할 수 있음), 전체 페이지 새로고침 이전까지 지속된다.
💡 알아두면 좋은점
POST
요청은 자동으로 중복 제거되지 않는다.
fetch
를 사용할 수 없는 경우, React는 요청의 수명 동안 데이터를 수동으로 캐시할 수 있는 cache
함수를 제공한다.
두 가지 유형의 데이터가 있다. 정적 데이터와 동적 데이터다.
기본적으로 Next.js는 자동으로 정적 패치를 수행한다. 이는 데이터가 빌드 시간에 패치되고 캐시되며 각 요청에 재사용된다는 것을 의미한다. 개발자는 정적 데이터의 캐싱과 유효성 재검사 방법을 제어할 수 있다.
정적 데이터를 사용하는 데는 아래와 같은 두 가지 이점이 있다.
그러나 데이터가 사용자에게 개인화되거나 항상 최신 데이터를 패치하려는 경우, 요청을 동적으로 표시하고 각 요청마다 데이터를 패치하고 캐시하지 않을 수 있다.
캐싱은 데이터를 원본 소스에서 각 요청마다 다시 패치할 필요가 없도록 특정 위치(예: 콘텐츠 전송 네트워크)에 저장하는 과정이다.
Next.js Cache는 전역적으로 분산될 수 있는 영구 HTTP 캐시
이다. 이는 캐시가 자동으로 확장되고 플랫폼(예: Vercel)에 따라 여러 지역에서 공유될 수 있다는 것을 의미한다.
Next.js는 fetch()
함수의 옵션 객체를 확장하여 각 서버 요청마다 영구 캐싱 동작을 설정할 수 있게 한다. 컴포넌트 수준의 데이터 패치와 함께, 데이터가 사용되는 위치에서 직접 응용 프로그램 코드 내에서 캐싱을 구성할 수 있다.
서버 렌더링 중에 Next.js가 fetch를 만나면, 데이터가 이미 캐시에 있는지 확인한다. 있으면 캐시된 데이터를 반환하고, 그렇지 않으면 데이터를 패치하여 미래 요청을 위해 저장한다.
💡 알아두면 좋은점
fetch
를 사용할 수 없는 경우, React는 요청의 수명 동안 데이터를 수동으로 캐싱할 수 있도록 cache
함수를 제공한다.
재검증(Revalidation)은 캐시를 삭제하고 최신 데이터를 다시 패치하는 과정이다. 데이터가 변경되고 전체 응용 프로그램을 다시 빌드하지 않고도 최신 버전이 표시되도록 하기 위해 유용하다.
Next.js는 두 가지 유형의 재유효화(재검증)를 제공한다.
백그라운드(Background)
: 특정 시간 간격으로 데이터를 재검증한다.요청에 따른(On-demand)
: 데이터가 업데이트될 때마다 데이터를 재검증한다.스트리밍(Streaming)과 서스펜스(Suspense)는 React의 새로운 기능으로, UI의 렌더링 단위를 점진적으로 렌더링하고 점전적으로 클라이언트에 스트리밍하는 것을 가능하게 한다.
서버 컴포넌트와 중첩된 레이아웃을 사용하면, 데이터를 명시적으로 요구하지 않는 페이지의 일부를 즉시 렌더링하고, 데이터를 가져오는 부분에는 로딩 상태를 보여줄 수 있다. 이렇게 하면 사용자가 페이지 전체가 로드되기를 기다릴 필요 없이 상호작용을 시작할 수 있다.
이전의 getServerSideProps
, getStaticProps
및 getInitialProps
와 같은 Next.js 데이터 패칭 방법은 새로운 App Router에서 지원되지 않는다. 그러나 여전히 Pages Router에서 사용할 수 있다.
[ 출처 ]
https://nextjs.org/docs/app/building-your-application/data-fetching