React Query 공부 (4)

JunSeok·2023년 1월 17일
0

react-query

목록 보기
5/11
post-thumbnail

앞서 pagination 구현할 때, 다음 페이지가 미리 준비되어 있지 않아 로딩창이 뜨는 좋지 않은 UX를 보여주었다. 이를 해결하기 위해 prefetching을 사용해보았다.

prefetching은 말 그대로 미리 cache data에 원하는 data를 추가하는 것이다.
prefetching 값은 곧바로 자동적으로 stale 상태가 되어 인자값이 바뀌면 곧바로 refetching 가능하다. 물론 이 또한 설정가능하다.
prefetching값은 refetching 되는 동안 보여지는 cache data로 쓰인다. 물론 cache data의 기한이 만료되지 않아야 가능하다.

공식 docs

구현

prefetch query는 query client의 메소드이다.
app.tsx에서 한차례 사용한 적이 있는데,query client는 useQueryClient hook으로 부를 수 있다.

currentPage값이 변할 때마다 prefetchig을 해주기 위해 useEffect 내에서 구현했다.

prefetchQuery는 useQuery의 인자와 매우 유사하다.
물론 query key는 같아야 할 것이다.
그리고 이전 값을 유지해주기 위해 옵션에 keepPreviousData를 true로 해준다.

import { useQueryClient } from 'react-query'
import { useEffect, useState } from "react";
const maxPostPage = 10;

const Posts = () => {
  const [currentPage, setCurrentPage] = useState(1);

  const queryClient = useQueryClient()

  useEffect(() => {
    if(currentPage < maxPostPage) {
      const nextPage = currentPage + 1
      queryClient.prefetchQuery(["posts", nextPage], () => fetchPosts(nextPage))
    }
  }, [currentPage])

  const { data, isError, error, isLoading } = useQuery(["posts", currentPage], () => fetchPosts(currentPage), { staleTime: 2000, keepPreviousData: true })
  if(isLoading) return <h3>Loading...</h3>
  if(isError) return <><h3>Oops, something went wrong</h3><p>{error.toString()}</p></>
  
  return (
      <div className="pages">
        <button disabled={currentPage <= 1} onClick={() => {
          setCurrentPage((previousValue) => previousValue-1)
        }}>
          Previous page
        </button>
        <span>Page {currentPage}</span>
        <button disabled={currentPage >= maxPostPage} onClick={() => {
          setCurrentPage((previousValue) => previousValue+1)
        }}>
          Next page
        </button>
      </div>
  );

}

isLoading vs isFetching

이전에 isLoading 과 isFetching을 다룬적이 있다.
prefetch를 배운 지금, 이 차이를 더 잘 구분할 수 있을 것이다.

다시 정리해보자

isFetching은 데이터를 fetching하는 비동기 query function이 끝나기 전 상태를 구분하는 것이며 아직 fetching 중이면 true, fetching이 끝났으면 false를 반환한다.

isLoading은 isFetching의 부분집합으로 isFetching이 true 이면서, 여기에 더해 query에 이전에 fetch한 cache data가 존재하지 않는 상태를 말한다.

그래서 isLoading이 true인 상태면 isFetching 또한 true이다.
isFetching은 cache data의 유무와 상관없이 data fetching 중이면 true이다.

isLoading과 isFetching 사용 방법 구분

이쯤 되면 둘 사이에 어떤 차이가 있는지 대충 감이 올 것이다.

로딩 문구를 띄울 때의 사용방법을 구분해보자면

  • isLoading
    • cache data가 없어서 렌더링 도중 화면에 보여줄 것이 전혀 없고, data fetching중 일때 로딩 문구를 띄우고 싶다면 isLoading을 사용
  • isFetching
    • 새로운 data를 fetching 할 때마다 로딩 문구를 띄우고 싶으면 isFetching을 사용한다.

근데 보통 로딩문구가 거의 없어야 UX가 좋다고 느껴진다. 그리고 prefetch의 포인트는 background에서 보여줄 cache data가 있다는 것이다.
그렇기 때문에 우리는 앞서 prefetching을 사용함으로써 보여줄 cache data를 미리 채워넣어 로딩문구를 없애고자 했는데, isFetching을 사용하면 데이터를 refetch할 때마다 true가 되어버리니 prefeth하는 이유가 없을 것이다.

다시 정리

isFetching은 데이터를 fetch하는 비동기 query function이 진행중이면 true이다.

isLoading은 데이터를 fetch하는 비동기 query function이 진행중이면서, 여기에 더해! 기존의 cache data가 전혀 없는 상태이면 true이다

profile
최선을 다한다는 것은 할 수 있는 한 가장 핵심을 향한다는 것

0개의 댓글