React

React : TanStack Query 심화 (Infinite Queries)

고래고래00 2024. 6. 14. 16:19

Infinite Queries

Data Fetching이 일어날 때 마다 기존 리스트 데이터에 Fetched Data를 추가할 때 유용

더보기 UI 또는 무한스크롤 UI 에 사용하기에 적합

더보기
const fetchProjects = async ({ pageParam = 0 }) => {
    const res = await fetch('/api/projects?cursor=' + pageParam)
    return res.json()
  }

  const {
    data,
    error,
    fetchNextPage,
    hasNextPage,
    isFetching,
    isFetchingNextPage,
    status,
  } = useInfiniteQuery({ // Infinite Queries에 사용하는 Hook
    queryKey: ['projects'],
    queryFn: fetchProjects,
    getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
    // useQuery와 사용법이 유사
    // 3번째 옵션인 getNextPageParam를 꼭 넣어줘야함
  })

(API 서버(ex.TMDB서버)에 데이터 요청시, 모든 데이터를 다 받는 게 아니라 특정 페이지의 데이터를 요청)

기존 useQuery는 캐시 컨텍스트에 데이터만 존재했음

페이지네이션이나 useInfiniteQuery는 캐시 컨텍스트에 데이터에다가 몇 번째 페이지의 데이터인지의 정보까지 존재 => 캐시 컨텍스트에서 pages, pageParams 같이 관리

(단, API 서버가 기능을 제공한다는 전제하)

 

실행 순서 정리

queryFn 실행

=> 캐시 데이터 등록 { pages, pageParam }

=> getNextPageParam 실행 (리턴된 NextPageParam는 훅 내부 메모리에 저장. 캐시에 저장X)

=> (NextPageParam 이 undefined이 아니면) hasNextPage true로 상태변경

=> fetchNextPage 실행

=> queryFn 실행 (이 때 내부적으로 저장되어 있던 NextPageParam을 queryFn 의 매개변수로 넘겨줌)

 

pages 와 pageParams 를 갖는 캐시 데이터

  • useQuery에서는 QueryFn의 반환값이 캐시데이터로 등록
  • useInfiniteQuery에서는 QueryFn의 반환값은 pages 배열의 요소로 추가되고, 매개변수로 받았던 pageParam은 pageParams 배열의 요소로 추가

 

useInfiniteQuery 사용 시 주의사항

  • 훅 내부적인 동작원리로 인해 예상보다 잦은 리렌더링이 발생
  • 연산량이 많은 코드가 있는 경우 useMemo 와 같은 memoization 적용을 특히 고려
  • 리렌더링이 발생한다고 해서 실제 브라우저 렌더링이 발생하는 것은 아님 (Virtual DOM 원리 이해 필요)

 

더보기