react-query v4 공식문서 : Paginated / Lagged Queries

👾·2022년 8월 11일
0

react-query

목록 보기
13/27
post-thumbnail

공식문서 : https://tanstack.com/query/v4/docs/guides/paginated-queries

Paginated / Lagged Queries

paginated 데이터를 렌더링하는것은 매우 일반적인 UI 패턴이며, React Query에서는 query key에 페이지 정보를 포함함로써 "그냥 작동"한다.

const result = useQuery(['projects', page], fetchProjects)

하지만, 이 간단한 예를 실행하면 다음과 같은 이상한 점을 발견할 수 있다. :

각각의 새 페이지가 완전히 새로운 쿼리로 취급되기 때문에 UI가 successloading 상태로 이동한다.

이러한 경험은 최적이 아니며 안타깝게도 오늘날 많은 툴이 작동을 고집하고 있다. 하지만 React Query는 아니다! 짐작했겠지만, React Query에는 keepPreviousData라는 놀라운 기능이 포함되어 있어 이러한 문제를 해결할 수 있다.

Better Paginated Queries with keepPreviousData

쿼리에 대한 pageIndex(또는 커서)를 이상적으로 증가시키고자하는 다음 예를 생각해보라. 만약 우리가 useQuery를 사용한다면, 그것은 기술적으로 여전히 잘 작동하겠지만, UI는 각 페이지나 커서에 대해 서로 다른 쿼리가 생성되고 삭제될 때 successloading 상태로 이동할 것이다. keepPreviousData를 true로 설정하면 다음과 같은 몇가지 새로운 이점을 얻을 수 있다.

  • 쿼리 키가 변경되었더라도 새 데이터를 요청하는동안, 마지막으로 성공적으로 fetch한 데이터를 사용할 수 있다.
  • 새 데이터가 도착하면, 이전 data가 원활하게 교환되어 새 데이터가 표시된다.
  • isPreviousData는 쿼리가 현재 제공하는 데이터가 무엇인지 알 수 있게 한다.
function Todos() {
  const [page, setPage] = React.useState(0)

  const fetchProjects = (page = 0) => fetch('/api/projects?page=' + page).then((res) => res.json())

  const {
    isLoading,
    isError,
    error,
    data,
    isFetching,
    isPreviousData,
  } = useQuery(['projects', page], () => fetchProjects(page), { keepPreviousData : true })

  return (
    <div>
      {isLoading ? (
        <div>Loading...</div>
      ) : isError ? (
        <div>Error: {error.message}</div>
      ) : (
        <div>
          {data.projects.map(project => (
            <p key={project.id}>{project.name}</p>
          ))}
        </div>
      )}
      <span>Current Page: {page + 1}</span>
      <button
        onClick={() => setPage(old => Math.max(old - 1, 0))}
        disabled={page === 0}
      >
        Previous Page
      </button>{' '}
      <button
        onClick={() => {
          if (!isPreviousData && data.hasMore) {
            setPage(old => old + 1)
          }
        }}
        // Disable the Next Page button until we know a next page is available
        disabled={isPreviousData || !data?.hasMore}
      >
        Next Page
      </button>
      {isFetching ? <span> Loading...</span> : null}{' '}
    </div>
  )
}

Lagging Infinite Query results with keepPreviousData

일반적이진 않지만, keepPreviousData 옵션은 useInfiniteQuery hook에서도 완벽하게 작동한다. 따라서 무한 쿼리 키가 변경되는 동안 유저가 계속해서 캐시된 데이터를 볼 수 있도록 원활하게 할 수 있다.

0개의 댓글