예를 들어 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 를 재실행 하는 것으로 생각됩니다.