무한 스크롤
리액트 쿼리에서 무한 스크롤을 구현하려면 useInfiniteQuery를 사용하면 된다. 전체 wrapper 컴포넌트로는 react-infinite-scroller 라이브러리의 InfiniteScroll를 사용하면 된다.
-react-infinite-scroller의 npm 사이트
https://www.npmjs.com/package/react-infinite-scroller
react-infinite-scroller
Infinite scroll component for React in ES6. Latest version: 1.2.6, last published: a year ago. Start using react-infinite-scroller in your project by running `npm i react-infinite-scroller`. There are 466 other projects in the npm registry using react-infi
www.npmjs.com
사용법
useInfiniteQuery
const initialUrl = "https://swapi.dev/api/species/";
const fetchUrl = async (url) => {
const response = await fetch(url);
return response.json();
};
const {
data,
fetchNextPage,
hasNextPage,
isLoading,
isFetching,
isError,
error,
} = useInfiniteQuery(
"sw-species",
({ pageParam = initialUrl }) => fetchUrl(pageParam),
{
getNextPageParam: (lastPage) => lastPage.next || undefined,
}
);
전체적으로 보면 useQuery와 비슷한 부분이 많다.
fetchNextPage는 더 많은 데이터가 필요할 때 어떤 함수를 실행할지 InfiniteScroll 컴포넌트(react-infinite-scroller)에 지시한다.
hasNextPage는 수집할 데이터가 더 있는지 알려주는 boolean형 데이터이다.
pageParam은 맨 처음에 불러올 페이지이며 초기 페이지 값을 initialUrl에 저장했다.
getNextPageParam은 다음 요청에 사용될 pageParam을 지정해 준다. 만약 다음 불러올 데이터가 없으면 undefined를 주고 이러면 hasNextPage도 false가 된다.
리턴값
if (isLoading) return <div className={"loading"}>Loading...</div>;
if (isError) return <div>Error! {error.toString()}</div>;
return (
<>
{isFetching && <div className={"loading"}>Loading...</div>}
<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>
</>
);
isFetching을 하게되면 페이지가 새로고침되어 스크롤이 위로 올라가게 된다. 그렇기에 데이터들도 같이 따라가게 하기 위해 저 위치에 isFetching을 하면 다음 데이터를 불러올 때 "Loading..."이란 문구가 뜨고 스크롤이 현 위치에 유지된다.