FrontEnd/Vue

[Vue-Query] useQuery

Grace 2023. 4. 20. 16:24

useQuery Docshttps://tanstack.com/query/v4/docs/vue/reference/useQuery

데이터 조회 상태

Promise 기반 메서드와 함께 쿼리를 사용하여 서버에서 데이터를 가져올 수 있습니다. 메서드가 서버의 데이터를 수정하는 경우 mutation을 사용하는 것이 좋습니다.

import { useQuery } from '@tanstack/vue-query'

// fetchTodoList가 todoList를 조회하는 api 입니다.
const { data, isLoading, isError, isSuccess, error } = useQuery({ 
  queryKey: ['todos'], 
  queryFn: fetchTodoList 
})

쿼리 함수는 Promise를 반환하는 모든 함수가 될 수 있습니다. https://tanstack.com/query/v4/docs/vue/guides/query-functions#queryfunctioncontext
고유 키는 애플리케이션(쿼리클라이언트) 전체에서 쿼리를 다시 가져오고, 캐싱하고, 공유하기 위해서 사용됩니다.
https://metadataplanning.atlassian.net/wiki/spaces/data/pages/105840714

  • isLoading: 쿼리에 아직 데이터가 없습니다. boolean으로 리턴됩니다.
  • isSuccess: 쿼리가 성공했고 데이터를 사용할 수 있습니다. boolean으로 리턴됩니다.
  • isError: 쿼리에 오류가 발생했습니다. boolean으로 리턴됩니다.
  • error: 쿼리가 isError 상태인 경우 error를 통해 오류를 확인할 수 있습니다.
  • data: 쿼리가 isSuccess 상태인 경우 데이터를 사용할 수 있습니다.

대부분은 isLoading으로 상태를 확인하고 isError로 오류인지, 성공인지 확인한 후 데이터를 사용할 수 있다고 가정하고 성공적인 상태를 렌더링합니다.

만약, boolean 상태로 리턴받고 싶지 않다면 status 상태를 이용할 수 있습니다.

const { status, data } = useQuery({ 
  queryKey: ['todos'], 
  queryFn: fetchTodoList 
})

console.log(status) /*'error' 혹은 'loading'
                      성공한 상태는 data의 값이 있는지 없는지에 따라서 확인할 수 있습니다 */

이 외에도 fetchStatus 를 통해서도 상태를 확인할 수 있습니다.

const { fetchStatus, data } = useQuery({ 
  queryKey: ['todos'], 
  queryFn: fetchTodoList 
})
  • fetching: 쿼리를 가져오는 중입니다.
  • paused: 쿼리를 가져오려고 했지만 일시 중지 되었습니다.
  • idle: 쿼리가 현재 아무 작업도 수행하지 않습니다.

이렇게 상태가 분리 되는 이유는 백그라운드에서 데이터를 가져오고 있는 상태에 대해서 확인할 수 있기 때문입니다.

쿼리가 success 상태인 경우 fetchStatus는 idle 상태이지만, 만약 백그라운드에서 데이터를 다시 가져오고 있다면 fetching 상태일 수 있습니다.

컴포넌트에 마운트 된 직후 데이터가 없는 경우 상태는 loading 이고 fetchStatus는 fetching 이지만, 만약 네트워크 연결이 원활하지 않다면 fetchStatus 상태가 paused 일 수 있습니다.

이렇게 각 쿼리의 status에 따라서 백그라운드의 상태(fetchStatus)가 다를 수 있기 때문에 두 가지를 모두 알아두면 비동기 로직의 분기를 다루기에 좋습니다.

만약 단순히 백그라운드에서 데이터를 불러오고있는지의 상태를 불린 값으로 받기를 원한다면 useIsFetching() 메서드를 사용하면 됩니다.

<script setup>
import { useIsFetching } from '@tanstack/vue-query'

const isFetching = useIsFetching()
</script>

<template>
  <div v-if="isFetching">Queries are fetching in the background...</div>
</template>

refetch

만약 어떤 동작 후 데이터를 다시 조회해서 가져와야 하는 상황이 생긴다면 refetch를 통해 데이터를 다시 조회할 수 있습니다. (예를 들어, 게시글 리스트를 조회했는데 검색어 variable을 전달하여 다시 조회해야 할 경우)

const { data, refetch } = useQuery(['boards'], fetchBoards)

하지만 만약 단순한 로직이 아닌, 데이터 통신 후 우리가 불러와야 할 데이터 자체에 갱신이 생긴 경우라면 다음 두가지 방법에 의해 데이터를 다시 조회할 수 있습니다. (예를 들어, 게시글 리스트를 조회했는데 게시글을 등록했기 때문에 새로운 게시글 리스트를 조회해야 하는 경우)

const createBoard =() => {
// 게시글을 등록하는 로직
...
  queryClient.invalidateQueries(['boards']) // boards 쿼리를 무효화시켜 재조회
  queryClient.refetchQueries(['boards']) // 쿼리를 무효화 시키지 않고 단순히 재조회
}

만약 mutaion을 통해 받아오는 데이터의 컬럼과 기존 데이터 리스트의 컬럼이 동일하다면 이런식으로 작성할 수도 있다.

function useUpdateTitle() {
  return useMutation(updateTitle, {
    onSuccess: (newTodo) => {
      // ✅ 투두 상제 정보 업데이트
      queryClient.setQueryData(['todos', 'detail', newTodo.id], newTodo)

      // ✅ 업데이트 된 투두를 포함하는 모든 목록 업데이트
      queryClient.setQueriesData(['todos', 'list'], (previous) =>
        previous.map((todo) => (todo.id === newTodo.id ? newtodo : todo))
      )
    },
  })
}

네트워크 모드(fetch policy)

데이터를 조회할 때 어떻게 작동해야 하는지 구별하기 위해서 세 가지의 다른 네트워크 모드를 제공합니다.

const { data } = useQuery(
  ['auth-list'], 
  fetchAuthList, 
  { networkMode: 'always'} // 'online', 'always', 'offlineFirst'
)

queryKey, queryFn 등은 생략해서 작성할 수 있습니다. 다만, 만약 순서를 바꿔 작성하고자 한다면 꼭 key 값을 명시해서 작성해야 합니다.

useQuery에서 세번째 인자로 받는 값은 데이터를 조회할 때 어떤 옵션으로 조회할 것인지를 작성합니다.
여기에 네트워크 모드를 작성할 수 있으며 총 세가지의 옵션이 있습니다. (작성하지 않으면 online이 default)

  • online: 오직 활성화된 네트워크 연결 상태일 때만 동작한다고 가정한다.(= 네트워크가 연결되지 않을 경우에 queryFn이 실행되지 않는다) 네트워크 연결이 없다면 paused 상태가 됩니다.
  • always: 네트워크 연결 여부에 관계없이 쿼리 함수를 항상 실행하고 paused 상태가 되지 않습니다. 실패할 경우 바로 error 상태로 변경됩니다.
  • offlineFirst: 네트워크 연결 여부과 관계 없이 쿼리 함수가 실행되고 만약 실패할 경우 paused 상태가 됩니다. 이 모드의 경우 오프라인 상태에서 캐싱된 데이터가 있다면 캐싱된 데이터를 정상 데이터로 반환합니다.

여러 개의 쿼리를 한 번에 조회하기: https://tanstack.com/query/v4/docs/vue/guides/parallel-queries
하나의 쿼리가 조회되면 그 다음 쿼리를 조회하기: https://tanstack.com/query/v4/docs/vue/guides/dependent-queries
무한 스크롤 쿼리 조회하기: https://tanstack.com/query/v4/docs/vue/guides/infinite-queries

'FrontEnd > Vue' 카테고리의 다른 글

[Vue-Query] persistQueryClient  (0) 2023.04.24
[Vue-Query] useMutation  (0) 2023.04.20
[Vue-Query] @tanstack/vue-query  (0) 2023.04.20
[Vue3] v-model props  (0) 2023.04.20
[Vue] Vue-Daum-Postcode  (0) 2023.04.18