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

👾·2022년 8월 11일

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가 success 및 loading 상태로 이동한다.

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

Better Paginated Queries with keepPreviousData

쿼리에 대한 pageIndex(또는 커서)를 이상적으로 증가시키고자하는 다음 예를 생각해보라. 만약 우리가 useQuery를 사용한다면, 그것은 기술적으로 여전히 잘 작동하겠지만, UI는 각 페이지나 커서에 대해 서로 다른 쿼리가 생성되고 삭제될 때 success 및 loading 상태로 이동할 것이다. 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개의 댓글