카테고리 없음

[Nuxt] data fetch 재 호출 (useFetch)

Yeah-Panda 2025. 1. 1. 01:23

예를 들어 useFetch 를 이용하여 user 정보를 불러오는 코드가 있다고 가정합니다.

<script lang="ts" setup>
const committedQuery: Ref<string> = ref('');
const query: Ref<string> = ref('');

const onSubmitCommittedQuery = (event: Event) => {
  committedQuery.value = query.value;
}

const {data,  status, execute} = await useFetch<{users: Array<User>}>(
  `https://dummyjson.com/users/search?q=${committedQuery.value}`, { 
    lazy: true,
    watch: [committedQuery]
  }
)
const users: Ref<Array<User>> = computed(() => {
  return data.value?.users as Array<User>;
});
</script>
<template>
  <h1 class="text-3xl my-8">Users</h1>
  <UButton type="button" @click="execute">Refresh</UButton>
  <form @submit.prevent="onSubmitCommittedQuery" class="form">
    <UInput type="text" v-model="query" />
    <UButton type="submit">Search</UButton>
  </form>
  <ul>
    <template v-if="status==='pending'">
      <li v-for="skeleton in 20" class="flex items-center space-x-4 h-[50px] pl-3">
        <USkeleton class="h-5 w-5" :ui="{ rounded: 'rounded-full' }" />
        <USkeleton class="h-2 w-[100px]" />
      </li>
    </template>
    <template v-else>
      <li v-for="user in users" :key="user.id">
        <span>{{ `${user.lastName} ${user.firstName}` }}</span>
        <img :src="user.image" :alt="user.email" />
      </li>
    </template>
  </ul>
</template>

useFetch 부분만 봅시다.

watch 옵션을 걸어서 committedQuery 값이 변경이 있을때마다 호출하는 것처럼 보이지만 실제는 submit  버튼을 눌러야 호출합니다.

query param 부분에 q=committedQuery.value  가 있지만 submit  할때마다 query가 갱신되지는 않습니다.

왜냐하면 컴포넌트가 초기화 될 때 committedQuery 는 빈 값입니다.

useFetch 함수는 실행되면서 빈 값인 committedQuery 조합하여 url을 구성합니다.

고정된 값임으로 이후 committQuery가 변경되더라도 반영 되지 않습니다.

 

아래와 같이 바꿀수 있습니다.

const {data,  status, execute} = await useFetch<{users: Array<User>}>(
  () => `https://dummyjson.com/users/search?q=${committedQuery.value}`, { 
    lazy: true,
    watch: [committedQuery]
  }
)

함수를 넘겨주는 것입니다. 위와 같은 형태로 정의하면 매번 useFetch 실행할때마다 함수를 실행하여 반환된 url 값으로  api  를 호출하게 됩니다. 사실 watch  는 여기서 불필요한 옵션 같으나 제거하게 되면 정상 동작하지 않습니다. useFetch 내부적으로 키값을 설정하는 부분이 있는 것 같은데 공식 문서를 좀 더 찾아봐야겠습니다.

 

저 방식외 조금 더 일반적인 방법이 있습니다.

const {data,  status, execute} = await useFetch<{users: Array<User>}>(
  `https://dummyjson.com/users/search`, { 
    lazy: true,
    query: {
      q: committedQuery
    }
  }
)

query parameter 를  query 속성을 이용해 전달합니다.

여기서 중요한 것은 q 를 전달할시 반응형 데이터를 전달해야합니다.

즉 committedQuery 자체를 전달해야하며 raw 데이터인  committedQuery.value 를 전달시 useFetch 는 제대로 동작하지 않습니다.

useFetch 내부적으로 query 값을 반응형 데이터를 받아 data fetch 를 재실행 하는 것으로 생각됩니다.