태그
목차

쿼리

생성일: 2024-03-16

수정일: 2024-03-16

쿼리 기초

컴포넌트나 커스텀 훅(Hook)에서 쿼리를 구독하려면, useQuery 등의 훅을 사용한다.

쿼리는 고유 키에 연결된 비동기 데이터 소스에 대한 선언적 종속성이다. 쿼리는 서버에서 데이터를 가져오기 위해 모든 프로미스 기반 메서드(GET 및 POST 메서드 포함)와 함께 사용할 수 있다. 메서드가 서버의 데이터를 수정하는 경우 대신 변형(Mutations)을 사용하는 것이 좋다.

컴포넌트 또는 커스텀 훅에서 쿼리를 구독하려면 useQuery 훅을 호출한다:

import { useQuery } from '@tanstack/react-query';

function App() {
  const info = useQuery({ queryKey: ['todos'], queryFn: fetchTodoList });
}

제공한 고유 키는 애플리케이션 전체에서 쿼리를 다시 가져오고, 캐싱하고, 공유하는 데 내부적으로 사용된다.

useQuery 가 반환하는 쿼리 결과에는 템플릿 작성 및 기타 데이터 사용에 필요한 쿼리에 대한 모든 정보가 포함되어 있다:

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

result 객체에는 생산성을 높이기 위해 알아야 할 몇 가지 매우 중요한 상태가 포함되어 있다. 쿼리는 주어진 순간에 다음 상태 중 하나다:

이러한 기본 상태 외에도 쿼리 상태에 따라 더 많은 정보를 확인할 수 있다:

대부분의 쿼리에서는 일반적으로 isPending 상태를 확인한 다음 isError 상태를 확인한 다음 마지막으로 데이터를 사용할 수 있다고 가정하고 성공 상태를 렌더링하는 것으로 충분하다:

function Todos() {
  const { isPending, isError, data, error } = useQuery({
    queryKey: ['todos'],
    queryFn: fetchTodoList,
  });

  if (isPending) {
    return <span>Loading...</span>;
  }

  if (isError) {
    return <span>Error: {error.message}</span>;
  }

  // 이 시점에서 `isSuccess === true`라고 가정할 수 있다.
  return (
    <ul>
      {data.map((todo) => (
        <li key={todo.id}>{todo.title}</li>
      ))}
    </ul>
  );
}

부울이 익숙하지 않다면 status 상태도 언제든지 사용할 수 있다:

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

  if (status === 'pending') {
    return <span>Loading...</span>;
  }

  if (status === 'error') {
    return <span>Error: {error.message}</span>;
  }

  // 또한 status === 'success', 'else' 로직도 작동한다.
  return (
    <ul>
      {data.map((todo) => (
        <li key={todo.id}>{todo.title}</li>
      ))}
    </ul>
  );
}

또한 데이터에 액세스하기 전에 pending 중 및 error 를 확인한 경우 타입스크립트는 data 타입을 올바르게 좁혀준다.

FetchStatus

status 필드 외에도 다음과 같은 옵션이 있는 추가 fetchStatus 프로퍼티가 제공된다:

왜 2가지 종류의 상태가 있을까?

백그라운드 리프레시 및 stale-while-revalidate 로직은 statusfetchStatus 에 대한 모든 조합을 가능하게 한다. 예를 들어:

따라서 쿼리는 실제로 데이터를 가져오지 않고도 pending 중 상태가 될 수 있다는 점에 유의한다.

정리해보면 다음과 같다: