react-query 개념 및 useQuery

useQuery 훅을 활용하는 기본 방법과 staleTime, retry 옵션에 대해 실습 코드로 학습함.


React Query

React Query는 API 호출을 단순하게 만들어주고, 내부적으로 캐싱, 재시도, refetch 등 많은 걸 자동으로 처리함

useQuery 기본 형태

const { data, isLoading, isError } = useQuery({
  queryKey: ["posts"],
  queryFn: fetchPosts,
  staleTime: 2000,
});

queryKey

  • 캐시를 구분하는 고유한 키
  • 배열 형태 → 파라미터별로 조합 가능

queryFn

  • 실제 데이터를 불러오는 비동기 함수

isLoading vs isFetching

  • isLoading
    • 쿼리를 처음 실행할 때만 true
    • 캐시된 데이터 없어서 최초 로딩 상태를 의미 ( 데이터 호출 실행 전)
    • 보통 처음 화면 로딩 스피너에 사용
    • isFetching의 하위 집합 개념임
  • isFetching
    • 쿼리가 실행되는 모든 순간 true
    • 처음 실행뿐 아니라 refetch(재요청) 중에도 true
    • 캐시가 있더라도 백그라운드에서 데이터를 다시 불러올 때 표시
    • 새로고침 UI나 “업데이트 중” 표시 등에 적합

요약

상태의미사용 예시
isLoading최초 로딩 중 (캐시 없음)처음 데이터 요청 시 화면 로딩
isFetching쿼리 실행 중 (캐시 상관없음)refetch, 창 포커스 복귀 등

staleTime

  • 데이터를 fresh 상태로 간주하는 시간(ms)
    • 이게 왜 필요할까 - 과도한 refetch를 방지가 가능하다.
    • 즉, API 호출(서버 비용?)을 줄이고 UX도 부드럽게 만들 수 있다
  • 이 시간이 지나면 React Query는 refetch 가능 상태로 간주함

그러면 staleTime은 언제 유용한가?

  • 브라우저 탭 이동 후 다시 돌아올 때
  • 창 포커스 됐을 때
  • invalidateQueries로 직접 무효화했을 때
상황예시
데이터가 자주 안 바뀌는 경우지역 정보, 공지사항 등
데이터 실시간성이 중요한 경우주식, 실시간 채팅 등

retry

  • react-query는 기본적으로 총 3번 호출을 실행함
    • 왜 3번 할까? 네트워크는 신뢰할 수 없기 때문에 일시적으로 자동 3번 재시도를 함
    • 이 retry 옵션을 사용 하면 호출횟수를 지정할 수 있다
  • 폼 전송 같은 건 retry: false로 꺼두는 게 안전함

자동 refetch 조건

전체 코드 예시

import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { fetchPosts } from "./api";
import { PostDetail } from "./PostDetail";
 
export function Posts() {
  const [selectedPost, setSelectedPost] = useState(null);
 
  const { data, isLoading, isError } = useQuery({
    queryKey: ["posts"],
    queryFn: fetchPosts,
    staleTime: 2000,
  });
 
  if (isLoading) return <h3>로딩중...</h3>;
  if (isError) return <h3>에러 발생...</h3>;
 
  return (
    <>
      <ul>
        {data.map((post) => (
          <li key={post.id} onClick={() => setSelectedPost(post)}>
            {post.title}
          </li>
        ))}
      </ul>
      <hr />
      {selectedPost && <PostDetail post={selectedPost} />}
    </>
  );
}
react-query 개념 및 useQuery