# Nuxt 3์˜ ๋ฐ์ดํ„ฐ ํ˜ธ์ถœ ๋ฐฉ๋ฒ•

๊ธฐ์กด Nuxt์—์„œ๋Š” asyncData ์†์„ฑ๊ณผ fetch ์†์„ฑ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ํ˜ธ์ถœํ–ˆ์Šต๋‹ˆ๋‹ค. Nuxt 3์—์„œ๋Š” ์ปดํฌ์ง€์…˜ ๋ฌธ๋ฒ• ํ˜•ํƒœ์ธ useAsyncData()์™€ useFetch()๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

# useAsyncData

useAsyncData๋Š” ๊ธฐ์กด asyncData ์†์„ฑ๊ณผ ๋™์ผํ•˜๊ฒŒ ํŽ˜์ด์ง€๋ฅผ ๊ทธ๋ฆฌ๊ธฐ ์ „์— ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๋ฐ์ดํ„ฐ ํ˜ธ์ถœ ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. ๊ธฐ์กด asyncData์™€์˜ ์ฐจ์ด์ ์€ ์ปดํฌ์ง€์…˜ ๋ฌธ๋ฒ•์œผ๋กœ ๋ฐ”๋€ ์ ๊ณผ ofetch๋ผ๋Š” HTTP ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ œ๊ณต๋˜๋Š” ์ ์ž…๋‹ˆ๋‹ค.

# useAsyncData ๊ธฐ๋ณธ ๋ฌธ๋ฒ•

๊ธฐ๋ณธ ๋ฌธ๋ฒ•์„ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

<!-- pages/user.vue -->
<script setup>
const { data, error } = await useAsyncData('user', () => $fetch('users/1'))
</script>

๊ณต์‹ ๋ฌธ์„œ์—์„œ ์•ˆ๋‚ด๋œ ๋ฐฉ์‹์œผ๋กœ ์ƒ์„ฑ๋œ Nuxt 3 ํ”„๋กœ์ ํŠธ์—์„œ๋Š” useAsyncData()์™€ ๊ฐ™์€ API๋ฅผ ๋ณ„๋„๋กœ ์ž„ํฌํŠธ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์œ„์™€ ๊ฐ™์ด ๋ทฐ ์ปดํฌ๋„ŒํŠธ์˜ script ํƒœ๊ทธ์— setup์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ฐ”๋กœ useAsyncData()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

useAsyncData()์˜ ์ฒซ ๋ฒˆ์งธ ์ธ์ž user๋Š” ๋ฐ”๋กœ API ์‘๋‹ต์„ ์บ์‹ฑํ•˜๊ธฐ ์œ„ํ•œ ์‹๋ณ„์ž์ž…๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์ธ์ž์—์„œ $fetch๋Š” Nuxt ํŒ€์—์„œ ์ž์ฒด ๊ฐœ๋ฐœํ•œ HTTP ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ ofetch ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ axios์™€ ๊ฐ™์€ ๋ณ„๋„์˜ HTTP ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” ofetch๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.

TIP

$fetch๋Š” Nuxt ํ”„๋กœ์ ํŠธ ์•ˆ์— ์žˆ๋Š” ๋ทฐ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ „์—ญ ๋ ˆ๋ฒจ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณ„๋„๋กœ ์ž„ํฌํŠธํ•˜๊ฑฐ๋‚˜ ์„ ์–ธํ•˜์ง€ ์•Š์•„๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

TIP

<script setup>์€ ๋ทฐ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ปดํฌ์ง€์…˜ API ๋ฌธ๋ฒ•์„ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ script setup ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด ๋ณด์„ธ์š”.

# useAsyncData ์ปค์Šคํ…€ ๋ฌธ๋ฒ• - ์™ธ๋ถ€ HTTP ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—ฐ๋™

๋งŒ์•ฝ axios์™€ ๊ฐ™์€ ๋Œ€์ค‘์ ์ธ HTTP ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

<!-- pages/user.vue -->
<script setup>
import {fetchUsers} from '../api/index.js'

const { data, error } = await useAsyncData(() => fetchUsers().then(response => response.data))
</script>

useAsyncData() API ์ฒซ ๋ฒˆ์งธ ์ธ์ž์— ์ต๋ช… ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜ ์„ ์–ธํ•˜๊ณ  ๋ฐ˜ํ™˜ ๊ฐ’์œผ๋กœ axios๋กœ ์ž‘์„ฑํ•ด ๋‘” API ํ•จ์ˆ˜๋ฅผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์™ธ๋ถ€ HTTP ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์—ฐ๊ฒฐํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ, ์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋ณ„๋„์˜ ํ‚ค ๊ฐ’์„ ์ •์˜ํ•˜์ง€ ์•Š์•˜๋Š”๋ฐ์š”. ํ‚ค ๊ฐ’์€ ์ •์˜ํ•˜์ง€ ์•Š๋”๋ผ๋„ ์ฝ”๋“œ๊ฐ€ ์„ ์–ธ๋œ ํŒŒ์ผ๊ณผ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ž๋™ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜๋„ ์ฝ”๋“œ๊ฐ€ ๋” ๋ณต์žกํ•ด ์งˆ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‚ค๋ฅผ ์ง€์ •ํ•ด ์ฃผ๋Š”๊ฒŒ ์ข‹์Šต๋‹ˆ๋‹ค.

<!-- pages/user.vue -->
<script setup>
import {fetchUsers} from '../api/index.js'

const { data, error } = await useAsyncData('user', () => fetchUsers().then(response => response.data))
</script>

# useFetch

useFetch๋Š” useAsyncData์™€ $fetch๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“  ๋ž˜ํ•‘ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ๋ž˜ํ•‘ ์ฝ”๋“œ๋ž€ ์ด๋ฏธ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ํ•œ๋ฒˆ ๋” ๊ฐ์‹ผ ์ฝ”๋“œ๋ฅผ ์˜๋ฏธํ•˜๋Š”๋ฐ์š”. ์•„๋ž˜ ์ฝ”๋“œ๋กœ ์ดํ•ดํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

<script setup>
// 1. useFetch๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ
const { data } = await useFetch('users/1');

// 2. useAsyncData๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ
const { data } = await useAsyncData(() => $fetch('users/1'))
</script>

์œ„ 2๊ฐœ ์ฝ”๋“œ๋Š” ๊ฐ™์€ ๋™์ž‘์„ ํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ useAsyncData์™€ $fetch๋ฅผ ๋งค๋ฒˆ ์„ ์–ธํ•˜์ง€ ์•Š๊ณ ๋„ ํŽธํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ๋” useFetch๋ผ๋Š” API๋กœ ์ฝ”๋“œ๋ฅผ ๊ฐ์‹ผ๊ฑฐ์ฃ . ์ด๋Ÿฐ์‹์œผ๋กœ ๋ณดํ†ต ์ฝ”๋“œ๊ฐ€ ๋„ˆ์ €๋ถ„ํ•ด์ง€๋Š” ๊ฑธ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ„๋„์˜ ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ์„œ ์ถ”์ƒํ™” ํ•˜๋Š” ๊ฒฝ์šฐ๋“ค์ด ์žˆ์Šต๋‹ˆ๋‹ค.

# useFetch ์žฅ๋‹จ์ 

useFetch๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ํŽธ๋ฆฌํ•œ ์ ์€ ์ฝ”๋“œ๋ฅผ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. useAsyncData๋ฅผ ์„ ์–ธํ•  ๋•Œ ์ง€์ •ํ•ด ์ฃผ์–ด์•ผ ํ•˜๋Š” ์œ ๋‹ˆํฌํ•œ ์‹๋ณ„์ž(ํ‚ค ๊ฐ’)๋„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, axios์™€ ๊ฐ™์€ ์™ธ๋ถ€ HTTP ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—ฐ๋™์€ ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ฐจ์ด์ ์„ ์ดํ•ดํ•œ ์ƒํƒœ์—์„œ ์ ์ ˆํ•œ API๋ฅผ ๊ณ ๋ฅด๋Š” ๊ฑธ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

# useAsyncData์™€ useFetch์˜ ๋ฐ˜ํ™˜ ๊ฐ’

๋‘ API ๋ชจ๋‘ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ˜ํ™˜ ๊ฐ’์„ ๋ฑ‰์–ด์ค๋‹ˆ๋‹ค.

const { data, pending, refresh, error } = await useFetch();
const { data, pending, refresh, error } = await useAsyncData();

useFetch๋„ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” useAsyncData๋ฅผ ์“ฐ๊ธฐ ๋•Œ๋ฌธ์— ๋‘ API์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ ๊ฐ’ ์†์„ฑ์€ ์ด๋ฆ„์—์„œ ์ถฉ๋ถ„ํžˆ ์—ญํ• ์ด ์œ ์ถ”๋˜์ง€๋งŒ ๊ฐ„๋‹จํžˆ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • data : API ์‘๋‹ต์˜ ๊ฒฐ๊ณผ
  • pending : ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๋”ฉ ์ค‘์ธ์ง€์˜ ์ƒํƒœ
  • refresh : ๋ฐ์ดํ„ฐ ํ˜ธ์ถœ API๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์†์„ฑ ํ•จ์ˆ˜. refresh()๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ค์‹œ ๋ถˆ๋Ÿฌ์™€์ง„๋‹ค. execute์™€ ๊ฐ™์€ ์—ญํ• 
  • error : ๋ฐ์ดํ„ฐ ํ˜ธ์ถœ์ด ์‹คํŒจํ–ˆ์„ ๋•Œ ๋ฐ˜ํ™˜๋˜๋Š” ์—๋Ÿฌ ๊ฐ์ฒด

์ด์™ธ์— status์™€ execute ์†์„ฑ๋„ ๋” ์žˆ๋Š”๋ฐ์š”. ์œ„ 4๊ฐœ ์†์„ฑ์ด๋ฉด ๊ฐœ๋ฐœํ•˜๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์„ ๊ฒ๋‹ˆ๋‹ค. ํ˜น์‹œ ๊ถ๊ธˆํ•˜์‹  ๋ถ„๋“ค์€ ๋‹ค์Œ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š” ๐Ÿ˜ƒ

Nuxt 3 ๊ณต์‹ ๋ฌธ์„œ - Return Values (opens new window)