React-query 더 불러오기 (Infinite Query)

SUN·2024년 7월 22일

React-query

목록 보기
9/9

1. 개요

페이지네이션 대신 불러오기 버튼으로 이어서 불러오게 한다. (useInfiniteQuery 사용)

2. 사용

  1. useQuery()를 useInfiniteQuery()로 바꿔줌
  2. initialPageParam과 getNextPageParam 옵션을 설정
  3. 페이지네이션과 달리 페이지 별로 데이터를 저장하는 게 아니기 때문에 쿼리키는 원래대로 사용
  4. 쿼리 함수도 pageParam이라는 값을 받아서 백엔드에 전달할 페이지값으로 사용하도록 변경
import {
  // ...
  useInfiniteQuery,
} from '@tanstack/react-query';

//

const {
  data: postsData,
  isPending,
  isError,
} = useInfiniteQuery({
  queryKey: ['posts'],
  queryFn: ({ pageParam }) => getPosts(pageParam, PAGE_LIMIT),
  initialPageParam: 0,
  getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
    lastPage.hasMore ? lastPageParam + 1 : undefined,
});

seQuery()에서는 data가 백엔드에서 받아 온 하나의 페이지 정보만 담고 있지만, useInfiniteQuery()에서는 data.pages에 배열의 형태로 모든 페이지의 정보를 담고 있게 된다.

첫번째 페이지의 데이터를 받아오면 data.page 배열의 0번 인덱스의 데이터가 저장되고 두번째 페이지로 넘어가면 data.page의 1번 인덱스 데이터가 저장된다.

pageParam 사용

initialPageParam: 0,
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
  lastPage.hasMore ? lastPageParam + 1 : undefined,
  • initialPageParam : 초기 페이지 설정값
  • getNextPageParam : 다음 페이지 설정값
    마지막 페이지의 hasmore가 true이면 다음 페이지, 아니라면 undefined

pageParam 값은 쿼리 함수의 파라미터로 전달되어 이를 이용하여 데이터 요청가능하다.

queryFn: ({ pageParam }) => getPosts(pageParam, PAGE_LIMIT),

다음 페이지 불러오기 (fetchNextPage())

const {
  data: postsData,
  isPending,
  isError,
  fetchNextPage,
} = useInfiniteQuery({
  queryKey: ['posts'],
  queryFn: ({ pageParam }) => getPosts(pageParam, PAGE_LIMIT),
  initialPageParam: 0,
  getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
    lastPage.hasMore ? lastPageParam + 1 : undefined,
});

// ...

return (
  ...
    <div>
      <button onClick={fetchNextPage}>더 불러오기</button>
    </div>
  ...
);

useInfiniteQuery()의 리턴 값 중 하나인 fetchNextPage() 함수를 사용.

getNextPageParam() 함수의 리턴 값이 undefined나 null이 아닌 경우, 해당 리턴 값을 쿼리 함수의 pageParam으로 전달해 그다음 페이지 데이터를 가져온다.

그래서 사용할 버튼에 onClick 함수로 fetchNextPage()를 등록해준다.

버튼 비활성화

const {
  data: postsData,
  isPending,
  isError,
  hasNextPage,
  fetchNextPage,
  isFetchingNextPage,
} = useInfiniteQuery({
  queryKey: ['posts'],
  queryFn: ({ pageParam }) => getPosts(pageParam, PAGE_LIMIT),
  initialPageParam: 0,
  getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) =>
    lastPage.hasMore ? lastPageParam + 1 : undefined,
});

// ...

return (
    ...
        <button
      onClick={fetchNextPage}
      disabled={!hasNextPage || isFetchingNextPage}
    >
      더 불러오기
    </button>
    ...
);

hasNextPage와 isFetchingNextPage를 이용

  • hasNextPage : 데이터가 없으면 비활성화
  • isFetchingNextPage : 데이터를 불러오는 중이면 비활성화
profile
안녕하세요!

0개의 댓글