Skip to main content
  1. Guides 리스트/
  2. Next.js 15와 React 19 실전 설계, 베스트 프랙티스 완벽 가이드/

Next.js 15와 React 19 데이터 로딩, 완벽 정복 가이드

·994 words·5 mins·
Next.js 15와 React 19 실전 설계, 베스트 프랙티스 완벽 가이드 - This article is part of a series.
Part 3: This Article

들어가며
#

Next.js 15React 19 환경에서 데이터를 가져오는 방법은 서버 컴포넌트, 클라이언트 컴포넌트, 캐시 전략, 스트리밍 등 선택지가 정말 다양한데요.

이번 글에서는 다양한 유스케이스별로 가장 최적화된 데이터 로딩 구현 방법을 자세히 알아볼 것입니다.

기본 방침
#

Next.js 15React 19에서 데이터를 가져올 때 따라야 할 세 가지 핵심 원칙이 있는데요.

이 원칙들을 기준으로 삼으면 대부분의 상황에 효과적으로 대응할 수 있습니다.

1. 서버 컴포넌트에서 직접 외부 API fetch하기
#

가장 먼저 고려해야 할 첫 번째 원칙은 서버 컴포넌트(Server Component)에서 외부 API를 직접 fetch하는 아주 간단한 방법인데요.

Next.js 15에서는 서버 컴포넌트가 표준이 되면서 서버에서 데이터를 가져오는 방식이 강력하게 권장되고 있습니다.

2. 클라이언트 로딩은 TanStack Query와 Route Handler 사용하기
#

만약 클라이언트 측에서 데이터를 가져와야 한다면, TanStack Query를 사용하고 반드시 Route Handler를 거쳐 외부 API를 호출해야 하거든요.

이렇게 구성하면 클라이언트 측 캐싱과 보안을 모두 효과적으로 관리할 수 있습니다.

3. 데이터 로딩의 지역화 (Colocation)
#

기본적으로 데이터가 필요한 컴포넌트에서 직접 데이터를 요청하는 것이 원칙인데요.

데이터가 필요한 곳에서 바로 가져오면 컴포넌트의 독립성이 높아지고, 결과적으로 재사용성도 크게 향상됩니다.

또한, 부모 컴포넌트에서 자식에게 데이터를 계속 내려보내는 소위 Props Drilling 문제까지 해결되는 장점도 있습니다.

유스케이스와 구현 방법
#

데이터를 가져오는 주요 유스케이스와 각 상황에 맞는 최적의 구현 방법을 정리해봤는데요.

하나씩 자세히 살펴보겠습니다.

유스케이스요약구현 방법
1초기 렌더링 (정적/반정적)
인증 불필요, 페이지 첫 로딩 시 데이터 요청서버 컴포넌트 + fetch + 데이터 캐시
2초기 렌더링 (동적/사용자 의존)
로그인 사용자 정보, 인증 필수 메뉴 등서버 컴포넌트 + fetch + (데이터 캐시)
3초기 렌더링 (클라이언트 전용 데이터)
DB 데이터를 클라이언트에서만 사용할 경우서버 컴포넌트 + fetch + 클라이언트 컴포넌트 + use
4사용자 액션 시
검색, 필터, 정렬 등 사용자 조작 시 데이터 요청클라이언트 컴포넌트 + useQuery + Route Handler + fetch
5초기 렌더링 + 사용자 액션 시 (하이브리드)
초기 로딩 후 사용자 조작으로 재요청서버 컴포넌트 + fetch + prefetchQuery + HydrationBoundary + dehydrate + useQuery
6의존성 쿼리
선행 입력값에 따라 다음 데이터 요청 (ex. 시/도 → 시/군/구)클라이언트 컴포넌트 + useQuery + Route Handler + fetch
7프리페치(Prefetch)
다음 페이지의 데이터를 미리 로딩 (ex. 링크 hover 시)서버 컴포넌트 + Link + prefetch 또는 클라이언트 컴포넌트 + router.prefetch

그럼, 각 유스케이스에 대해 더 자세히 알아보겠습니다.

1. 초기 렌더링 (정적/반정적 데이터)
#

이 패턴은 인증이 필요 없는 초기 화면 데이터를 서버에서 미리 가져와 데이터 캐시(Data Cache)에 저장해두고 재사용하는 방식인데요.

Next.js 15의 데이터 캐시는 fetch API의 응답을 서버에 영구적으로 저장해두기 때문에, 두 번째 요청부터는 외부 API를 호출하지 않고 캐시에서 바로 응답하여 성능이 비약적으로 향상됩니다.

카테고리 목록, 국가/지역 리스트 같은 마스터 데이터나 공지사항, 이용약관처럼 자주 바뀌지 않는 데이터를 가져올 때 주로 사용하거든요.

Next.js 15에서는 이 패턴과 바로 다음에 나올 2번 패턴(동적 데이터)을 데이터 로딩의 최우선 전략으로 삼는 것이 좋습니다.

2. 초기 렌더링 (동적/사용자 의존 데이터)
#

이 패턴은 인증이나 세션 정보에 의존하는 사용자별 고유 데이터를 서버에서 가져오는 경우인데요.

cookies()headers() 함수를 사용해 사용자를 식별하고, 해당 사용자에게 맞는 데이터를 초기 렌더링 시에 불러오는 것입니다.

대시보드의 사용자 통계, 마이페이지의 프로필 정보, 로그인한 사용자에게만 보이는 공지사항 등을 가져올 때 이 방식을 사용하는데요.

1번 패턴과의 가장 큰 차이점은 인증이 필요한지와 데이터 캐시가 필수적인지 여부입니다.

3. 초기 렌더링 (클라이언트 전용 데이터)
#

초기 렌더링에 필요하면서도 오직 클라이언트 컴포넌트에서만 사용될 데이터를 가져오는 경우인데요.

서버 컴포넌트에서 데이터를 요청한 뒤, Promise 객체를 그대로 클라이언트 컴포넌트에 넘겨주면 효율적인 스트리밍 렌더링을 구현할 수 있습니다.

폼(Form)의 초기값이나 클라이언트에서 상태 관리가 필요한 데이터를 가져올 때 이 패턴을 사용하거든요.

React 19use 훅을 활용하면 성능과 보안을 모두 챙기면서 클라이언트에서 유연하게 데이터를 처리할 수 있게 됩니다.

4. 사용자 액션 시
#

사용자의 특정 행동을 계기로 데이터를 가져오는 경우인데요.

TanStack Query와 Route Handler를 조합하면 클라이언트 측의 캐시를 효율적으로 관리하면서 데이터를 손쉽게 가져올 수 있습니다.

검색, 필터, 정렬, 페이지네이션, 모달 열기 등 사용자와의 상호작용에 따라 데이터를 요청할 때 이 방식을 사용하거든요.

TanStack Query의 캐시 기능 덕분에 동일한 조건으로 다시 요청할 때는 캐시된 데이터를 반환하여 불필요한 네트워크 요청을 막아줍니다.

참고로, 무한 스크롤을 위한 useInfiniteQuery처럼 특정 기능에 특화된 커스텀 훅이 있다면 적극적으로 활용해서 불필요한 코드를 줄이는 것이 좋습니다.

5. 초기 렌더링 + 사용자 액션 시 (하이브리드)
#

초기 렌더링은 서버 컴포넌트에서 처리하고, 그 이후의 사용자 액션에 따른 데이터 요청은 클라이언트 컴포넌트에서 TanStack Query로 처리하는 하이브리드 패턴인데요.

검색 페이지나 목록 페이지처럼 초기 데이터도 중요하지만, 사용자의 조작에 따른 데이터 갱신도 필요한 경우에 아주 유용한 방법입니다.

서버에서 prefetchQuery로 데이터를 미리 가져와 dehydrateHydrationBoundary를 통해 클라이언트에 전달하거든요.

이렇게 하면 첫 화면의 로딩 성능을 극대화하면서, 동시에 인터랙티브한 사용자 경험도 놓치지 않을 수 있습니다.

참고로 이 패턴에서는 데이터 캐시와 TanStack Query의 캐시를 함께 사용하면 관리가 복잡해지는데요.

따라서 데이터 캐시는 사용하지 않고 TanStack Query의 캐시로 일원화해서 관리하는 것이 좋습니다.

6. 의존성 쿼리 / 타입어헤드 / 점진적 검색
#

어떤 데이터의 선택이나 입력값에 의존해서 다음 데이터를 가져와야 하는 경우인데요.

TanStack Query의 enabled 옵션을 활용하면, 의존하는 값이 존재할 때만 쿼리를 실행하도록 간단하게 제어할 수 있습니다.

예를 들어, 시/도를 선택해야 시/군/구 목록을 가져오거나, 검색어 자동완성 기능을 구현할 때 이 패턴을 사용하거든요.

enabled 옵션으로 불필요한 요청을 막고, 입력값에 대한 디바운스(debounce) 처리나 캐시를 활용하면 사용자 경험과 서버 부하를 모두 개선할 수 있습니다.

7. 프리페치 (Prefetch)
#

사용자가 다음에 이동할 가능성이 높은 페이지의 경로와 데이터를 미리 읽어두는 프리페치 기법인데요.

이를 통해 페이지 전환 시 사용자가 느끼는 로딩 속도를 크게 향상시킬 수 있습니다.

Next.js 15에서는 Link 컴포넌트의 prefetch 속성이나 router.prefetch() 메서드를 사용해 프리페치를 제어하거든요.

대시보드에서 설정 화면으로 이동하거나, 탭을 전환하는 등 사용자의 다음 행동이 예측될 때 이 기법을 사용하면 거의 로딩 시간 없는 네이티브 앱 같은 경험을 제공할 수 있습니다.

다만, 목록 페이지처럼 수많은 링크가 있는 곳에서 모든 링크를 프리페치하면 불필요한 요청이 대량으로 발생할 수 있으니 신중하게 적용해야 합니다.

구현 방법
#

Next.js 15에서 프리페치를 구현하는 방법은 두 가지가 있는데요.

상황에 맞게 선택해서 사용하면 됩니다.

    1. Link 컴포넌트의 prefetch 속성

    Link 컴포넌트가 사용자의 화면(viewport)에 들어오는 순간 자동으로 프리페치가 시작됩니다.

    1. router.prefetch() 메서드

    클라이언트 컴포넌트에서 useRouter 훅을 사용해 원하는 시점에 수동으로 프리페치를 실행할 수 있습니다.

마치며
#

이번 글에서는 Next.js 15React 19 환경에서 데이터를 가져오는 다양한 유스케이스와 그에 맞는 최적의 구현 방법에 대해 알아봤는데요.

데이터 로딩은 애플리케이션의 성능과 사용자 경험에 직접적인 영향을 미치는 아주 중요한 요소입니다.

서버 컴포넌트와 클라이언트 컴포넌트의 특징을 잘 이해하고, 각 레이어의 캐시 전략을 효과적으로 활용하는 것이 성능을 극대화하는 핵심이거든요.

상황에 맞는 최적의 데이터 로딩 전략을 선택하는 데 이 글이 도움이 되었으면 합니다.

끝까지 읽어주셔서 정말 감사합니다.

Next.js 15와 React 19 실전 설계, 베스트 프랙티스 완벽 가이드 - This article is part of a series.
Part 3: This Article