React Query Pagination 구현

penguin·2022년 3월 25일
4

pagination을 구현하며 공부하게된 React Query 사용법을 공유하고자 합니다.


useQuery

이번에 React Query를 이용하며 cache와 pagination을 구현하며 사용한 기능은 useQuery입니다. github api를 이용하여 검색어를 받아 레포지토리를 검색하고 결과 데이터를 caching하기 위해 사용했습니다.

// const { data, isFetching } = useQuery(queryKey, queryFn, { options })

const { data, isFetching } = useQuery<RepoResult>(
    ["repos", { name: query.repo as string, page: page }],
    () => fetchReposWithQuery<RepoResult>(query.repo as string, page),
    { keepPreviousData: true, refetchOnWindowFocus: true, staleTime: 60000, enabled: !!query.repo }
  );

useQuery는 파라미터로 queryKey, queryFn, options를 가집니다.

queryKey

queryKey는 배열 또는 string을 받을 수 있습니다. queryKey가 변경됐을 때 useQuery에서 data를 업데이트합니다.
queryKey로 데이터를 구분하여 다른 컴포넌트에서 useQuery로 동일한 키를 입력하면 데이터를 api 요청없이 사용할 수 있습니다.
queryKey를 배열로 할 때 순서를 주의해야합니다

  • [key, name, page] !== [key, page, name]
    순서가 바뀌면 key가 다르다고 인식되어 새로 api를 호출합니다.
    이럴 때 객체를 이용하면 좋습니다.
  • [key, {name: name, page: page}] === [key, {page: page, name: name}]
    객체 안에서 순서를 다르게 입력해도 같은 key로 인식합니다.

queryFn

queryFn은 데이터를 호출하는 함수를 받습니다.

fetchReposWithQuery 함수는 인자로 레포지토리 이름, 페이지를 받아 github api 검색 데이터를 받아오는 함수입니다.

const fetchReposWithQuery = async <T>(repo: string, page: number): Promise<T> => {
 const info = await axios.get(
   `https://api.github.com/search/repositories?q=${repo}+in:name&page=${page}&per_page=10`,
   {
     headers: headers,
   }
 );
 return info.data;
};

option

저는 keepPreviousData, refetchOnWindowFocus, staleTime, enabled option을 사용했습니다.

keepPreviousData

keepPreviousData: 데이터 refetch될 때 이전 데이터를 유지하는 지를 정하는 옵션입니다. false로 하면 page가 바뀔 때 data가 비워진 후 새로운 data를 받아옵니다. true이면 새로운 data를 다 받아온 후 data를 교체합니다.

  • keepPreviousData가 true일 때 isSuccess, isLoading 값이 처음 데이터를 불러오기 시작할 때, 불러온 후 바뀌고 그 후로는 바뀌지 않습니다.
  • keepPreviousData가 false일 때 isSuccess, isLoading 값이 queryKey가 바뀔 때마다 변합니다.

pagination을 구현할 때는 true로 하는게 좋습니다.

refetchOnWindowFocus

true일 때 window에 focus되었을 때 데이터를 refetch합니다.

staleTime

cache 데이터의 유효기간을 ms단위로 설정합니다. cache 데이터를 refetch할 때 staleTime이 지났다면 queryFn를 호출하여 데이터를 불러온 후 cache를 교체합니다.

enabled

enabled가 false라면 데이터를 불러오지 않습니다. useQuery가 return하는 refetch 메소드 등을 이용하여 수동으로 refetch를 해야합니다.

  • 이 옵션을 설정하지 않았을 때 query.repo가 없다면 undefined를 검색어로 api를 호출한 검색결과가 fetch되는 문제가 있었습니다.
    enabled: !!query.repo를 통해 query.repo가 undefined일 때 data를 반환하지 않게 하였습니다.

useQuery return

useQuery의 return 값 중에 저는 data, isSuccess, isLoading, isFetching을 사용했습니다.

data

queryFn을 호출하여 얻은 결과 또는 queryKey에 따른 cache data를 반환합니다.

isSuccess

queryFn이 호출되었을 때 false를 반환합니다. queryFn가 정상적으로 완료되었을 때 true를 반환합니다.

isLoading

cache data가 없고 queryFn을 통한 fetch가 진행 중일 때 true를 반환합니다. fetch가 끝나면 false를 반환합니다.

isFetching

cache data를 불러올 때, queryFn을 호출할 때 항상 true를 반환합니다.
loading상태를 나타내고 싶을 때 주로 사용합니다.

pagination을 구현할 때 keepPreviousData가 false라면 page가 바뀔 때마다 useQuery는 새로운 query라고 생각하여 isSuccess와 isLoading 값이 변하게 됩니다. keepPreviousDatat를 true로 하면 첫 페이지에서만 isSuccess와 isLoading 값이 변하고 페이지 이동할 때 더이상 isSuccess와 isLoading은 변하지 않게 됩니다.


react-query의 useQuery를 사용하면 쉽게 cache를 구현할 수 있어서 편리합니다.

출처: https://react-query.tanstack.com/

profile
힘내자

0개의 댓글