[React Query] useInfiniteQuery infinite scroll 무한 스크롤

gu·2023년 11월 27일
0

React Query

목록 보기
8/9
post-thumbnail

*환경셋팅
react-infinite-scrollerreact17버전에서 지원하지 않기 때문에 플래그 설치가 필요!

  • npm i--legacy-peer-deps
  • npm install react-query 리액트쿼리 설치 (버전3)
  • npm install @react-query/react-query-devtools 리액트쿼리 개발자도구 설치
  • npm install react-infinite-scroller

💻 infinite scroll

  • 무한스크롤은 사용자가 스크롤할 때마다 새로운 데이터를 가져온다.
  • useInfiniteQuery라는 훅을 사용
  • 업데이트된 상태가 쿼리 키를 업데이트하고 쿼리 키가 데이터를 업데이트 한다.

🖤 useInfiniteQuery와 useQuery의 차이점

  • useQuery: 데이터는 단순히 함수에서 반환됨
  • useInfiniteQuery: 객체는 두개의 프로퍼티를 가지고 있다.
    -데이터 페이지 객체의 배열인 페이지page: 하나의 useQuery에서 받는 데이터에 해당
    -pageParams(각페이지의 매개변수가기록): 많이 사용되진 않지만 모든 쿼리는 페이지배열에 고유한 요소를 가지고 있고 그 요소는 해당 쿼리에 대한 데이터에 해당한다. 즉 페이지가 진행되면서 쿼리도 바뀐다. pageParams은 검색된 쿼리의 키를 추적한다.

🖤 적용

import InfiniteScroll from "react-infinite-scroller";
import { Species } from "./Species";
import { useInfiniteQuery } from "react-query";
const initialUrl = "https://swapi.dev/api/species/";
const fetchUrl = async (url) => {
    const response = await fetch(url);
    return response.json();
};

export function InfiniteSpecies() {
    const { data, fetchNextPage, hasNextPage, isLoading, isFetching, isError, error } = useInfiniteQuery(
        "sw-people",
        // initialUrl에서 시작해 pageParam 값으로 fetchUrl을 실행
        ({ pageParm = initialUrl }) => fetchUrl(pageParm),
        {
            // getNextPageParam은 이전페이지(lastPage)의 다음 프로퍼티를 불러와 새 페이지 데이터가 있을때마다 pageParm에 지정해줌
            getNextPageParam: (lastPage) => lastPage.next || undefined, // 함수값이 null인 경우 undefined
        }
    );
    // 캐시된 데이터가 없어 새데이터를 가져올 때는 데이터가 정의되지 않았기 때문에 에러가 발생하므로 isLoading이나 isErrorㅀ 조기반환 실행
    if (isLoading) return <div className="loading">Loading...</div>;
    if (isError) return <div>Error!{error.toString()}</div>;

    return (
        <>
            {/* 로딩이나 에러상황이 아닐경우 fetching */}
            {isFetching && <div className="fetching">Fetching</div>}
            <InfiniteScroll loadMore={fetchNextPage} hasMore={hasNextPage}>
                {/* pages에 pageParam이 실행될 때마다 필요한 데이터 배열이 들어있으므로 배열에 매핑할 때 각페이지에는  결과물에 매핑이 덮어씌워지게 된다. */}
                {data.pages.map((data) => {
                    return data.results.map((person) => {
                        return (
                            <Species
                                key={person.name}
                                name={person.name}
                                language={person.language}
                                averageLifespan={person.averageLifespan}
                            />
                        );
                    });
                })}
            </InfiniteScroll>
        </>
    );
}
  • pageParam: 기본 초기값으로 지정. fetchNextPage가 이 pageParam의 다음 페이지가 있는지 결정한다.
  • hasNextPage: 수집할 데이터가 더 있는지를 결정하는 boolean형태
  • fetchNextPage:더 많은 데이터가 필요할 때, 어느 함수를 실행하는지 지시하는 역할을 한다. 그래서 <InfiniteScroll> 라이브러리에서 loadMore에 적용시키면, 더 불러올 데이터가 있을 때마다 알아서 로드해준다.
  • getNextPageParam: 다음 페이지를 가져오기 위한 함수이다. 매개변수로 lastPageallPosts를 사용할 수 있다.

✔ Output


아웃풋을 확인해보면 패칭된 데이터에서 더나아가 스크롤을 내렸을 때 Fetching표시가 뜨는 것을 확인할 수 있다. 패칭이완료되고 stale
상태가되면 이후 데이터를 스크롤을 내리면서 확인할 수 있다. 이것을 반복적으로 무한 스크롤을 구현할 수 있다.

참고
유데미-리액트쿼리
리액트쿼리 참고블로그

0개의 댓글

관련 채용 정보