minstudio

최적화된 데이터 패칭 (useFetch)

서버 사이드 렌더링(SSR) 환경에서 일반적인 fetch 함수를 쓰면, 서버에서 한 번 데이터를 부르고 클라이언트 브라우저가 다시 똑같은 데이터를 부르는 이중 호출(Double Fetch) 문제가 발생합니다.

Nuxt 4에서는 이를 막기 위해 useFetch라는 강력한 내장 함수를 제공하여, 서버에서 가져온 데이터를 HTML과 함께 묶어서 클라이언트로 배달해 줍니다.

📡 useFetch의 하이드레이션 폭포수(Waterfall) 흐름 🖥️ Nuxt SSR 서버 1. useFetch() 실행하여 API 호출 2. JSON 응답 데이터를 HTML에 직렬화 HTML + Payload 전송 <script id="__NUXT_DATA__"> 🚀 🌐 클라이언트 브라우저 3. 중복 API 호출 없음! 전달받은 Payload를 그대로 재사용
<!-- ==========================================
// 📂 app/pages/movies.vue (데이터 패칭 예제)
// ========================================== -->
<template>
  <div class="p-6">
    <h1 class="text-2xl font-bold mb-4">인기 영화 목록</h1>

    <!-- 데이터가 로딩 중일 때 보여줄 스켈레톤 UI -->
    <div v-if="status === 'pending'" class="text-blue-500 font-bold">
      데이터를 불러오는 중입니다...
    </div>

    <!-- 에러가 발생했을 때 보여줄 에러 메시지 -->
    <div v-else-if="error" class="text-red-500 font-bold">
      이런! 데이터를 불러오지 못했습니다.
    </div>

    <!-- 로딩이 끝나면 화면에 리스트를 렌더링 -->
    <ul v-else class="grid grid-cols-1 gap-4">
      <!-- data 변수에 API 응답값이 담겨있습니다. -->
      <li 
        v-for="movie in data" 
        :key="movie.id" 
        class="bg-white p-4 shadow rounded"
      >
        <h2 class="text-xl font-bold">{{ movie.title }}</h2>
        <p class="text-gray-600">{{ movie.overview }}</p>
      </li>
    </ul>
  </div>
</template>

<script setup>
// useFetch는 API 주소에 요청을 보내고, 
// 그 결과를 반응형(reactive) 변수 묶음으로 돌려줍니다.
const { data, status, error } = await useFetch('https://api.example.com/movies', {
  // 캐시 효율을 위한 키(key) 지정 가능
  key: 'popular-movies',
  // 서버 응답에서 필요한 데이터만 골라오기 (Pick)
  // pick: ['id', 'title', 'overview'] 
})
</script>
최적화된 데이터 패칭 (useFetch) | Minstudio