useInfiniteQuery()
- 다음 쿼리 추적
- 쿼리 결과로 데이터 이외의 페이지 관련 쿼리가 return됨
- 이전 쿼리와 다음 쿼리, 전체 페이지 수를 알려줌
- react-qeury 개발자도구는 node 노드 환경이 production이 아닐때만 실행됨
- 즉 개발모드일 때만 실행됨
- useQuery()와의 차이
- 반환된 데이터 프로퍼티 형식이 다름 2개의 프로퍼티를 가지는 객체
- pages - 해당 페이지의 객체 배열 쿼리 값
- pageParams - 각 페이지의 매개변수가 기록되어 있음 - 잘 사용하지 않음
- 무한스크롤 작동 원리
useInfiniteQuery("sw-people", ({pageParam = defaultUrl}) => fetchUrl(pageParam))
- pageParam이 fetchUrl의 매개변수로 들어가 적절한 페이지를 가져옴
- pageParam의 현재값은 유지됨!
- getNextPageParam이 다음 페이지에 대한 url을 가져오고 그 값이 pageParam에 할당됨
// 무한스크롤 예시 코드
import InfiniteScroll from 'react-infinite-scroller'
import { Person } from './Person'
import { useInfiniteQuery } from 'react-query'
const initialUrl = 'https://swapi.dev/api/people/'
const fetchUrl = async (url) => {
const response = await fetch(url)
return response.json()
}
export function InfinitePeople() {
const { data, fetchNextPage, hasNextPage, isLoading, isFetching, isError, error } = useInfiniteQuery(
'sw-people',
({ pageParam = initialUrl }) => fetchUrl(pageParam),
{
getNextPageParam: (lastPage) => lastPage.next || undefined
}
)
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) =>
pageData.results.map((person) => {
return (
<Person key={person.name} name={person.name} hairColor={person.hair_color} eyeColor={person.eye_color} />
)
})
)}
</InfiniteScroll>
</>
)
}
useInfiniteQuery() 함수 호출
인수로 키값과, pageParam, getNextPageParam을 입력한다.
pageParam은 호출할 페이지 url이고 getNextPageParam은 지난 페이지에서 다음 페이지의 값을 pageParam에 넣어준다. 값이 없을 경우 undefined를 할당하여 다음 페이지가 없다는 걸 명시한다.
InfiniteScroll 컴포넌트 loadMore에는 fetchNextPage, hasMore에는 hasNextPage를 할당한다
fetchNextPage는 값이 더 필요할 때 작동하는 함수이고 hasNextPage는 다음 페이지가 있는지 확인한다.
useInfiniteQuery()의 결과로 나오는 data는 pages라는 데이터가 별도로 있고 pages를 매핑하며 뿌려주어야한다.
각각 페이지를 다시 매핑하는 형식으로 데이터를 화면에 뿌려준다.