🔥 쿼리 함수

379자
4분

쿼리 함수는 프로미스를 반환하는 어떤 함수라도 될 수 있습니다. 이 프로미스는 데이터를 반환하거나 오류를 던져야 합니다.

다음은 모두 유효한 쿼리 함수 구성의 예입니다:

typescript
useQuery({ queryKey: ['todos'], queryFn: fetchAllTodos })
useQuery({ queryKey: ['todos', todoId], queryFn: () => fetchTodoById(todoId) })
useQuery({
  queryKey: ['todos', todoId],
  queryFn: async () => {
    const data = await fetchTodoById(todoId)
    return data
  },
})
useQuery({
  queryKey: ['todos', todoId],
  queryFn: ({ queryKey }) => fetchTodoById(queryKey[1]),
})
 
typescript
useQuery({ queryKey: ['todos'], queryFn: fetchAllTodos })
useQuery({ queryKey: ['todos', todoId], queryFn: () => fetchTodoById(todoId) })
useQuery({
  queryKey: ['todos', todoId],
  queryFn: async () => {
    const data = await fetchTodoById(todoId)
    return data
  },
})
useQuery({
  queryKey: ['todos', todoId],
  queryFn: ({ queryKey }) => fetchTodoById(queryKey[1]),
})
 

오류 처리와 던지기

TanStack Query가 쿼리에 오류가 발생했다고 판단하려면, 쿼리 함수가 오류를 던지거나 거부된 프로미스를 반환해야 합니다. 쿼리 함수에서 던진 모든 오류는 쿼리의 오류 상태에 유지됩니다.

typescript
const { error } = useQuery({
  queryKey: ['todos', todoId],
  queryFn: async () => {
    if (somethingGoesWrong) {
      throw new Error('이런!')
    }
    if (somethingElseGoesWrong) {
      return Promise.reject(new Error('이런!'))
    }
 
    return data
  },
})
 
typescript
const { error } = useQuery({
  queryKey: ['todos', todoId],
  queryFn: async () => {
    if (somethingGoesWrong) {
      throw new Error('이런!')
    }
    if (somethingElseGoesWrong) {
      return Promise.reject(new Error('이런!'))
    }
 
    return data
  },
})
 

기본적으로 오류를 던지지 않는 fetch와 다른 클라이언트 사용하기

axiosgraphql-request 같은 대부분의 유틸리티는 실패한 HTTP 호출에 대해 자동으로 오류를 던지지만, fetch 같은 일부 유틸리티는 기본적으로 오류를 던지지 않습니다. 이런 경우에는 직접 오류를 던져야 합니다. 다음은 인기 있는 fetch API를 사용해 이를 구현하는 간단한 방법입니다:

typescript
useQuery({
  queryKey: ['todos', todoId],
  queryFn: async () => {
    const response = await fetch('/todos/' + todoId)
    if (!response.ok) {
      throw new Error('네트워크 응답이 정상이 아닙니다')
    }
    return response.json()
  },
})
 
typescript
useQuery({
  queryKey: ['todos', todoId],
  queryFn: async () => {
    const response = await fetch('/todos/' + todoId)
    if (!response.ok) {
      throw new Error('네트워크 응답이 정상이 아닙니다')
    }
    return response.json()
  },
})
 

쿼리 함수 변수

쿼리 키는 가져오는 데이터를 고유하게 식별하는 데 사용될 뿐만 아니라, QueryFunctionContext의 일부로 쿼리 함수에 편리하게 전달됩니다. 항상 필요한 것은 아니지만, 이를 통해 필요한 경우 쿼리 함수를 추출할 수 있습니다:

typescript
function Todos({ status, page }) {
  const result = useQuery({
    queryKey: ['todos', { status, page }],
    queryFn: fetchTodoList,
  })
}
 
// 쿼리 함수에서 키, 상태, 페이지 변수에 접근할 수 있습니다!
function fetchTodoList({ queryKey }) {
  const [_key, { status, page }] = queryKey
  return new Promise()
}
 
typescript
function Todos({ status, page }) {
  const result = useQuery({
    queryKey: ['todos', { status, page }],
    queryFn: fetchTodoList,
  })
}
 
// 쿼리 함수에서 키, 상태, 페이지 변수에 접근할 수 있습니다!
function fetchTodoList({ queryKey }) {
  const [_key, { status, page }] = queryKey
  return new Promise()
}
 

QueryFunctionContext

QueryFunctionContext는 각 쿼리 함수에 전달되는 객체입니다. 다음과 같은 요소로 구성됩니다:

  • queryKey: QueryKey: 쿼리 키
  • signal?: AbortSignal
  • meta: Record<string, unknown> | undefined
    • 쿼리에 대한 추가 정보를 담을 수 있는 선택적 필드입니다

추가로, 무한 쿼리는 다음 옵션을 전달받습니다:

  • pageParam: TPageParam
    • 현재 페이지를 가져오는 데 사용되는 페이지 매개변수
  • direction: 'forward' | 'backward'
    • deprecated
    • 현재 페이지 가져오기의 방향
    • 현재 페이지 가져오기의 방향에 접근하려면 getNextPageParamgetPreviousPageParam에서 pageParam에 방향을 추가하세요.

YouTube 영상

채널 보기
인터셉터와 RxJS로 캐시 시스템 구축하기 | NestJS 가이드
NestJS 커스텀 데코레이터 인자 전달 및 파이프 검증 활용법 | NestJS 가이드
class-validator 와 DTO | NestJS 가이드
NestJS 역할 기반 접근 권한 부여 - Guard, Reflector | NestJS 가이드
API 응답 지연과 복잡한 에러, NestJS 인터셉터로 관리하는 방법 | NestJS 가이드
NestJS 인터셉터에서 map 연산자로 응답을 변환하는 방법 | NestJS 가이드
NestJS 커스텀 데코레이터, createParamDecorator 사용 | NestJS 가이드
존 매카시가 들려주는 인공지능의 탄생 이야기