npm install --legacy-peer-deps
앞으로 사용할 react infinite scoller의 의존성을 설정한 방식 때문에
--legacy-peer-deps 플래그를 사용하지 않으면 오류가 난다.
useInfiniteQuery('sw-people',({ pageParam = defaultUrl }) => fetchUrl(pageParam)
InfiniteQuery에는
getNextPageParam: (lastPage, allPages) 옵션이 있다.
다음 페이지 혹은 모든 페이지에 대한 데이터를 가져오고, pageParam을 업데이트 해준다
사용해줄 페이지에 useInfiniteQuery를 임포트해주자
import { useInfiniteQuery } from 'react-query';
그런다음 함수형 컴포넌트에서 사용
export function InfinitePeople() {
const { data, fetchNextPage, hasNextPage } = useInfiniteQuery(
'sw-people',
반환해줄 객체는 data 이다.
페이지를 계속 로드할 때 여기에 데이터의 페이지가 포함될것
fetchNextPage는 더 많은 데이터가 필요할 때 어느 함수를 실행할지를
infiniteScroll에 지시하는 역할을 한다.
hasNextPage는 수집할 데이터가 더 있는지를 결정하는 boolean 이다.
export function InfinitePeople() {
const { data, fetchNextPage, hasNextPage } = useInfiniteQuery(
'sw-people',
({ pageParam = initialUrl }) => fetchUrl(pageParam),
useInfiniteQuery는 몇가지 인수를 사용하는데 쿼리키, 쿼리 함수를 입력해줬다.
이 쿼리 함수는 객체 매개변수를 받고 프로퍼티 중 하나로 pageParam을 가지고 있다.
useInfiniteQuery의 모든것이 pageParam 에 달려있다.
왜냐면
pageParam은 fetchNextPage가 어떻게 보일지 결정하고 다음 페이지가 있는지 결정하기 때문이다.
fetchUrl이 하는 일은 Url인 pageParam을 가져와서 json을 반환해 준다.
pageParam은 기본값을 줘야한다. useInfiniteQuery를 처음 실행할 땐 pageParam이 설정돼있지 않기 때문이다.
이제 getNextPageParam에 옵션을 줘보자!
export function InfinitePeople() {
const { data, fetchNextPage, hasNextPage } = useInfiniteQuery(
'sw-people',
({ pageParam = initialUrl }) => fetchUrl(pageParam),
{
getNextPageParam: (lastPage) => lastPage.next || undefined,
}
);
이 옵션은 lastPage 를 가진 함수이다.
필요하면 allPage를 두번째 인자로 넣을 수 있지만 지금은 필요가 없기 때문에 lastPage만 넣어줬다.
lastPage를 가져와서 pageParam을 lastPage.next로 작성해주었다.
fetchNextPage를 실행하면 next 프로퍼티가 무엇인지에 따라 마지막 페이지에 도착한 다음 pageParam을 사용하게 되는 형식이다.
hasNextPage는 undefined를 반환하는지, 아닌지에 따라 결정이 된다.
그래서 lastPage.next가 거짓이면 undefined를 반환하도록 만들어주었다.
나는infinite scroller을 사용하여 무한스크롤을 구현할 것이다
npm i react-infinite-scroller
시작하기 전에 flow를 보면
infiniteScroller은 두개의 프로퍼티가 있다.
무한스크롤 컴포넌트는 스스로 페이지의 끝에 도달함을 인식하고 fetchNextPage를 불러온다.
그러면 데이터 프로퍼티에서 데이터에 접근할 수 있는데
useInfiniteQuery 컴포넌트에서 나온 객체를 이용한다
배열인 페이지 프로퍼티를 이용해서 그 페이지 배열의 맵을 만들어 데이터를 표시할 수 있게
해주는 역할을 한다.
코드를 작성해보쟈
const {
data,
fetchNextPage,
hasNextPage,
isLoading,
isFetching,
isError,
error,
} = useInfiniteQuery(
'sw-people',
({ pageParam = initialUrl }) => fetchUrl(pageParam),
{
getNextPageParam: (lastPage) => lastPage.next || undefined,
}
);
useInfiniteQuery 를 실행해 반환된 객체에서 나온 프로퍼티들을 나열, 쿼리키 설정, 쿼리함수를 작성해주었다.
이 쿼리 함수는 useInfiniteQuery의 pageParams를 쓰는데
initialUel 에서 시작해 pageParam 값으로 fetchUrl을 실행한다.
그 다음 getNextPageParam은 이전페이지(lastPage)의 다음 프로퍼티를 불러와
새 페이지 데이터가 있을 때마다 pageParam에 지정해준다 .
API에서 지정해준대로 이 함수의 값이 null 인 경우에는 undefined 값을 낸다.
if (isLoading) return <div>Loading...</div>;
if (isError) return <div>Error! {error.toString()}</div>;
return (
<InfiniteScroll loadMore={fetchNextPage} hasMore={hasNextPage}>
{data.pages.map((pageData) => {
return pageData.results.map((person) => {
console.log(person);
return (
<Species
key={person.name}
name={person.name}
language={person.language}
averageLifespan={person.average_lifespan}
/>
);
});
})}
</InfiniteScroll>
);
InfiniteScroll 컴포넌트에서
loadMore함수는 fetchNextPage가 되고
fetchNextPage는 useInfiniteQuery의 영향을 받아 어떤 쿼리 함수든
pageParam 값을 쓰게 되고 pageParam값은 데이터가 추가되면 갱신된다.
hasMore함수는 infiniteScroll 컴포넌트가 계속 데이터를 불러올지를 결정하는 역할을 한다. 이 함수는 hasNextPage 프로퍼티의 영향을 받고 pageParam이 정의되지 않아 거짓이 되는 경우도 lastPage.next를 통해 다음 프로퍼티가 없거나 프로퍼티가 거짓인 경우도 정의했다!
이렇게 다 설정해준 뒤 데이터를 매핑해주면 끝!