useInfiniteQuery 사용해보기

김현진·2022년 9월 20일
0

react-query

목록 보기
1/1

useInfiniteQuery에 대해서 지난번 설명이 부족한거 같아 간단하게 프로젝트를 생성해 간단요약을 해보겠습니다. (처음보는 것들이 많아 헷갈리기 때문에 정리용)

사용한 라이브러리(react-query 버전이 3입니다.)

"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-infinite-scroller": "^1.2.4",
"react-query": "^3.39.2",
"react-scripts": "4.0.3",
"web-vitals": "^1.1.1"

우선 알고 있어야 할 내용부터 정리하기

  • fetch function

    이 표현을 잘모르면 헷갈릴 수 있는데 서버로부터 데이터를 가져오는 함수라고 생각하면 됩니다.
    (밑에 처럼 비동기함수)

//example
  const fetchUrl = async (page) => {
  const response = await fetch(`https://swapi.dev/api/people?page=${page}`);
  return response.json();
};
  • query function

    useInfiniteQuery의 두번째 인자값으로 함수형태이고 pageParam을 이용해서 fetch function으로 전달이 가능하다.

useInfiniteQuery('sw-people', ({ pageParam = 1 }) => {
    return fetchUrl(pageParam)
}
  • getNextPageParam

    useInfiniteQuery option값인데 리턴값이 true인 값이면 query function의 pageParam의 값으로 들어갑니다. falsy인 값이면 hasNextPage가 false가 됩니다.

    lastPage, allPages 두개의 인자값이 있는데 last Page는 쉽게 말하면 useInfiniteQuery를 이용해 호출된 가장 마지막에 있는 페이지 데이터라고 보면 되고 allPages는 useInfiniteQuery를 이용해 가져온 모든 데이터라고 보면됩니다.

{
  // 예를 들어 한번에 데이터를 10개씩 보여준다고 가정
  // maxPage는 서버에서 가져온 데이터 값중에 count값을 통해서 총 몇페이지가 있는지 확인
  // (total / 한번에 보여질 데이터)
  // nextPage는 현재까지 불러온 데이터의 길이에 1을 더해서 다음 fetch function의  page Param으로 전달
  // nextPage가 더크면 더이상 불러올 데이터가 없는거기 때문에 undefined를 리턴
  
  getNextPageParam: (lastPage, allPages) => {
  const maxPage = lastPage.count % 10 !== 0 ? lastPage.count  / 10 + 1  : lastPage.count  / 10 ; // 8
  const nextPage = allPages.length + 1;
  return nextPage <= maxPage ? nextPage : undefined;
  },
}
  • fetchNextPage
    다음 페이지의 데이터를 호출할 때 사용합니다.

결론

App.js

import "./App.css";
import { InfinitePeople } from "./people/InfinitePeople";

import { QueryClient, QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools'

const queryClient = new QueryClient();

function App() {
  return (
      <QueryClientProvider client={queryClient}>
          <div className="App">
              <h1>Infinite SWAPI</h1>
              <InfinitePeople />
              <ReactQueryDevtools />
          </div>
      </QueryClientProvider>
  );
}

export default App;

InfinitePeople.js


import InfiniteScroll from "react-infinite-scroller";
import { useInfiniteQuery } from 'react-query';
import { Person } from "./Person";

const fetchUrl = async (page) => {
  const response = await fetch(`https://swapi.dev/api/people?page=${page}`);
  return response.json();
};

export function InfinitePeople() {
  const { data, isLoading, isError, error, fetchNextPage,hasNextPage } = useInfiniteQuery('sw-people', ({ pageParam = 1 }) => {
    return fetchUrl(pageParam)
  }, {
    getNextPageParam: (lastPage, allPages) => {
      const maxPage = lastPage.count % 10 !== 0 ? lastPage.count  / 10 + 1  : lastPage.count  / 10 ; // 8
      const nextPage = allPages.length + 1;
      return nextPage <= maxPage ? nextPage : undefined;
    },
  })

  if(isLoading) return <div className='loading'>Loading...</div>
  if(isError) return <div className="error">{error.toString()}</div>


  return <InfiniteScroll loadMore={fetchNextPage} hasMore={hasNextPage}>
    {data.pages.map((pageData) => {
      return pageData.results.map((person) => {
        return (
            <Person
              key={person.name}
              name={person.name}
              hairColor={person.hair_color}
              eyeColor={person.eye_color}
            />
        )
      })
    })}
  </InfiniteScroll>;
}

profile
기록의 중요성

0개의 댓글