Recent Posts
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
관리 메뉴

개발자 박가나

[241129 TIL] 본캠프 43일차 (useInfiniteQuery) 본문

내일배움캠프

[241129 TIL] 본캠프 43일차 (useInfiniteQuery)

gnchoco97 2024. 11. 29. 20:32

TanStack Query에서 제공하는 Hook으로, 페이지 단위로 데이터를 가져오는 기능을 제공한다.

 

useInfiniteQuery는 각 페이지 데이터를 data.pages 배열에 누적해서 저장한다. 이를 위해서 API 응답 값에는 각 페이지의 데이터와 다음 페이지에 대한 정보가 포함되어 있어야 한다.

 

필수 데이터

  • data : 현재 페이지의 데이터 배열
  • nextPage : 다음 페이지 번호 (없을 경우 null 또는 undefined)

선택 데이터

  • totalPages : 전체 페이지 수
  • totalItems : 전체 데이터 항목 수

 

작동 방식

초기 로드

queryFn이 실행되어 첫 페이지의 데이터를 가져와서 data.pages[0]에 저장된다.

 

다음 페이지 로드

fetchNextPage 호출 시 queryFn이 실행되어 새로운 데이터를 가져와서 data.pages[1], data.pages[2], ...에 순차적으로 저장된다.

 

캐싱

queryKey를 기준으로 데이터를 캐싱함으로써 중복 요청을 방지한다.

 

 

예시 코드

import { useInfiniteQuery } from "@tanstack/react-query";

const fetchPhotos = async ({ page = 1 }) => {
  const response = await fetch(`https://api.example.com/photos?page=${page}`);
  const result = await response.json();
  return { data: result.data, nextPage: result.next };
};

const Home = () => {
  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage, 
    isLoading,
    isError,
  } = useInfiniteQuery({
    queryKey: ["photos"],
    queryFn: fetchPhotos,
    getNextPageParam: (lastPage) => lastPage.nextPage,
  });

  if (isLoading) return <div>Loading...</div>;
  
  if (isError) return <div>Error loading data</div>;

  return (
    <div>
      {data.pages.map((page, index) => (
        <div key={index}>
          {page.data.map((photo) => (
            <p key={photo.id}>{photo.title}</p>
          ))}
        </div>
      ))}
      {hasNextPage && <button onClick={fetchNextPage}>Load More</button>}
    </div>
  );
};

export default Home;