useAsyncData with Nuxt 3 — Course part 15

https://www.youtube.com/watch?v=3xeAElHzMe4&list=PL8HkCX2C5h0XT3xWYn71TlsAAo0kizmVc&index=15

 

유튜브 강의를 참고하고 있습니다.

 


1. useAsyncData

useAsyncData()는 비동기 로직의 resolve 동작을 반환한다.

useFetch('url')과 useAsyncData('url', () => $fetch('url')) 와 거의 동일하게 동작한다.

 

  • server/api/products.ts

async, await를 사용해 비동기 함수를 만든다.

함수가 동작하면 1초 뒤에 productCount가 1씩 증가한다.

let productCount = 0

export default async() => {
  await new Promise((resolve) => {
    setTimeout(() => {
      resolve(productCount++)
    }, 1000)
  })

  return { productCount }
}

 

  • pages/index.vue

useAsyncData()를 사용해 data를 가지고 온다.

클릭 이벤트를 만들어 버튼을 클릭하면 data가 새로고침 된다.

<script setup lang="ts">
const { data: productCount, pending } = await useAsyncData('count', () => $fetch('/api/products'))

const refresh = () => refreshNuxtData('count')

</script>

<template>
  <div v-if="pending">
    <p>pending</p>
    {{ productCount }}
  </div>

  <div v-else>
    <p>resolve</p>
    {{ productCount }}
  </div>

  <button @click="refresh">Refresh</button>
</template>

 

2. useLazyAsyncData

  • pages/index.vue

useLazyAsyncData()를 사용하는 것만 제외하면 나머지는 동일한 코드이다.

얼핏 보면 차이점이 없는 것처럼 보이지만, 페이지 처음 진입 시 useLazyAsyncData()를 사용하면 v-if="pending" 부분이 나타나는 것을 볼 수 있다.

pending 상태의 화면 로직을 보여주고 싶을 때 사용한다.

<script setup lang="ts">
const { data: productCount, pending } = await useLazyAsyncData('count', () => $fetch('/api/products'))

const refresh = () => refreshNuxtData('count')

</script>

<template>
  <div v-if="pending">
    <p>pending</p>
    {{ productCount }}
  </div>

  <div v-else>
    <p>resolve</p>
    {{ productCount }}
  </div>

  <button @click="refresh">Refresh</button>
</template>

 


$fetch

$fetch는 Nuxt3에서 제공하는 전역 메서드이고, HTTP request를 만들 수 있다.

$fetch는 서버와 클라이언트 환경에서의 중복 호출 문제가 있기 때문에 클라이언트 사이드에서만 사용해야 한다.

서버 사이트 렌더링을 위해서는 useFetch나 useAsyncData를 사용해야 한다.

 

useFetch() vs useAsyncData()

2가지 메서드는 동일한 기능을 하는 것처럼 보이지만, 사용법에서 몇 가지 차이가 있다. 

그중 가능 큰 차이는 실행 context의 차이이다.

 

useAsyncData()는 page 값이 바뀌면 url의 params도 변경되지만, useFetch()는 page 값이 바뀌어도 params가 바뀌지 않는다.

 

확실히 이해한 부분이 아니기 때문에 실제로 사용해 보면서 공부가 더 필요하다..

 

 

 

참고자료

https://nuxt.com/docs/api/composables/use-fetch

https://nuxt.com/docs/api/composables/use-async-data

https://jongmin4943.tistory.com/entry/Nuxt3-fetch-useAsyncData-useFetch-%EC%9D%98-%EC%B0%A8%EC%9D%B4

useFetch, useLazyfetch with Nuxt 3 — Course part 14

https://www.youtube.com/watch?v=rU92oLYjTGY&list=PL8HkCX2C5h0XT3xWYn71TlsAAo0kizmVc&index=14

 

유튜브 강의를 참고하고 있습니다.

 


Data Fetching

Nuxt는 서버 또는 브라우저에서 데이터를 가져와 처리하는 컴포저블을 제공한다.

  • useFetch()
  • useAsyncData
  • $fetch

 


1. useFetch()

useFetch()는 컴포넌트 설정 기능 중에서 데이터 패칭을 수행하는 가장 간단한 방법이다.

 

  • server/api/products.json

data를 json 파일로 만든다.

[
  {
    "name": "책상",
    "price": "$50.99",
    "description": "책상입니다."
  },
  {
    "name": "의자",
    "price": "$30.99",
    "description": "의자입니다."
  },
  {
    "name": "컴퓨터",
    "price": "$999.99",
    "description": "컴퓨터입니다."
  }
]

 

  • server/api/products.ts

json 파일을 import 해 return 한다.

import data from './products.json'

export default defineEventHandler((event) => {
  return {
    data
  }
})

 

  • pages/index.vue

useFetch()를 사용해 data를 가지고 온다.

<script setup lang="ts">
const { data } = await useFetch('/api/products')

console.log(data)
</script>

<template>
  {{ data }}
</template>

 

{ data: products } 라고 변수 이름을 설정할 수도 있다.

결과는 동일하다.

<script setup lang="ts">
const { data: products } = await useFetch('/api/products')

console.log(toRaw(products.value))
</script>

<template>
  {{ products }}
</template>

 

2. useLazyFetch()

useLazyFetch()는 데이터 패칭을 하기 전(EventHandler가 resolve 되기 전)의 과정을 제공한다.

 

  • server/api/products.ts

asycn()과 setTimeout()을 사용해 data를 2초 뒤에 return 한다.

import data from './products.json'

export default defineEventHandler(async()=> {
  return new Promise<any>((resolve) => {
    setTimeout(() => {
      resolve(data)
    }, 2000)
  })
})

 

  • pages/index.vue

useLazyFetch()를 사용해 data를 가지고 온다.

이때 pending(보류: 초기 상태로 이행되기 전이나 거절되기 전의 상태)을 사용해 data를 가지고 오기 전에 화면 로직을 보여준다.

data가 화면에 보이기 전에 Loading 텍스트가 나오고, console.log도 그전에 실행되기 때문에 null 값이 찍힌다.

<script setup lang="ts">
const { data: products, pending } = await useLazyFetch('/api/products')

console.log(toRaw(products.value))
</script>

<template>
  {{ pending ? 'Loading' : products }}
</template>

 

  • nuxt.config.ts

만약 useLazyFetch()와 pending을 사용했는데도 새로고침 즉시 data가 나온다면 SSR 설정이 false인지 확인한다.

SSR은 서버에서 렌더링이 완료된 다음에 브라우저에 보여지기 때문에 useLazyFetch()가 동작하지 않는다.

export default defineNuxtConfig({
  devtools: { enabled: true },
  modules: [],
  ...
  ssr: false
})

+ Recent posts