React Query를 활용한 무한 스크롤 구현하기

Sean L.·2023년 4월 9일
5

React

목록 보기
2/4
post-thumbnail

무한스크롤은 왜 구현해야하나?

무한 스크롤을 구현하면 웹 사이트 소유자와 사용자 모두에게 여러 가지 이점이 있습니다.

웹 사이트 소유자의 경우 무한 스크롤은 원활한 브라우징 경험을 제공하여 사용자 참여 및 유지를 향상시킬 수 있습니다. 전통적인 페이지 매김을 사용하면 사용자는 처음 몇 페이지 이후 페이지를 포기하거나 관련 콘텐츠를 찾기 위해 많은 페이지를 스크롤하는 데 흥미를 잃습니다. 무한 스크롤은 새로운 콘텐츠를 항상 사용할 수 있도록 하여 사용자가 페이지에 더 오래 머물게 합니다.

무한 스크롤은 또한 서버 요청 및 페이지 다시 로드를 줄여 웹 사이트 성능을 향상시킵니다. 사용자가 전통적인 페이지 매김으로 페이지 끝에 도달하면 다음 페이지를 로드하기 위해 링크를 클릭해야 하므로 전체 페이지가 다시 로드됩니다. 무한 스크롤을 사용하면 페이지를 다시 로드할 필요 없이 다음 콘텐츠 세트가 자동으로 로드되므로 로드 시간이 단축되고 서버 요청이 줄어듭니다.

사용자에게 무한 스크롤은 보다 편리하고 효율적인 브라우징 경험을 제공합니다. 무한 스크롤을 통해 사용자는 새 페이지가 로드될 때까지 기다릴 필요 없이 많은 양의 콘텐츠를 빠르게 탐색할 수 있습니다. 또한 스크롤하면서 사용할 수 있는 콘텐츠가 얼마나 더 있는지 확인할 수 있으므로 사용 가능한 콘텐츠의 양을 더 잘 이해합니다.

전반적으로 무한 스크롤을 구현하면 사용자 참여가 향상되고 웹 사이트 성능이 향상되며 사용자에게 더 편리한 브라우징 경험을 제공할 수 있습니다.

무한 스크롤은 어떻게 구현하나?

무한 스크롤을 구현하는 것은 어려울 수 있지만 React-Queryreact-intersection-observer는 프로세스를 단순화하는 데 유용한 도구를 제공합니다.

우선 React-Query가 설치되어 있다 가정하고 추가로 무한 스크롤에 필요한
react-intersection-observer라는 라이브러리를 설치해야한다.

npm 사용시

npm i react-intersection-observer

yarn 사용시

yarn add react-intersection-observer

라이브러리를 설치했다면 이제 무한 스크롤을 직접 구현해보자.

무한스크롤 구현 예시

import { useInfiniteQuery } from "react-query";
import { MyInfinity } from "../api/main";

export function useInfinityList(type: number, monthDate: string, perPage = 10) {
    return useInfiniteQuery(
        "myInfinityList",
        async ({ pageParam = 0 }) =>
            MyInfinity(pageParam, perPage, type, monthDate),
        {
            getNextPageParam: (lastPage, pages) => {
                if (lastPage.data.total <= pages.length * perPage)
                    return undefined;
                return pages.length * perPage;
            }
        }
    );
}
  • 항목 목록에 대한 무한 스크롤 기능을 구현하기 위해 react-query 라이브러리의 useInfiniteQuery를 사용하는 커스텀 훅을 만들어 사용했다. 커스텀 훅은 type, monthDate 및 perPage의 세 가지 인수를 사용합니다.

  • 커스텀훅 내에서 쿼리 결과를 캐시하는 데 사용되는 "myInfinityList" 키로 useInfiniteQuery가 호출됩니다. 두 번째 인수는 pageParam, perPage, type 및 monthDate의 지정된 매개변수를 사용하여 MyInfinity API에서 데이터를 가져오는 비동기 함수입니다.

  • 'getNextPageParam' 함수는 로드할 페이지가 더 있는지 확인하는 데 사용됩니다. 데이터의 이전 페이지와 가져온 페이지의 현재 배열인 lastPagepages 인수를 각각 받습니다. 마지막 페이지의 총 항목 수가 현재 페이지 배열의 길이에 perPage를 곱한 값보다 작거나 같으면 더 이상 로드할 페이지가 없다는 의미이며 undefined가 반환됩니다. 그렇지 않으면 다음 페이지 매개변수는 현재 페이지 배열의 길이에 'perPage'를 곱한 값으로 계산됩니다.

import React, { useMemo, useState } from "react";
import { useInView } from "react-intersection-observer";
import { useMyInfinity } from "../../hooks/useMyInfinity";
import NONInfinity from "../../source/images/NonBill2.svg";
import * as m from "./style/MyInfinityStyle";

const MyInfinity = () => {
    const { ref, inView } = useInView();
    const [monthDate, setMonthDate] = useState(new Date());
    const [type, setType] = useState(2);
    const { data, fetchNextPage, hasNextPage, refetch } = useMyInfinityList(
        type,
        monthDate.toISOString().slice(0, 7)
    );
    const dispatch = useAppDispatch();
    useMemo(() => {
        refetch();
    }, [monthDate, type]);

    useMemo(() => {
        if (
            inView &&
            hasNextPage &&
            data?.pages[data.pages.length - 1].data.data.length > 10
        ) {
            fetchNextPage();
        }
    }, [inView]);

    return (
      
        <m.MyInfinityWrap>               
                    <m.MyInfinityInfoBody>
                        {data?.pages.map((page: any, i: any) => (
                            <div key={i}>
                                {page.data.data.length === 0 && (
                                    <object data={NONInfinity} />
                                )}
                                {page.data.data.map((page: any) => (
                                    <m.InfinityInfoLi
                                        ref={ref}
                                        color={page.status}
                                    >
                                        <m.MyInfinityTitleHeader>
                                            <m.MyInfinityInfoCompanyName>
                                                {page.name}
                                           </m.MyInfinityInfoCompanyName>
                                            <m.MyInfinityInfoStatus
                                                color={page.status}
                                            >
                                                {page.status}
                                            </m.MyInfinityInfoStatus>
                                        </m.MyInfinityInfoTitleHeader>
                                        <m.MyInfinityInfoTitle>
                                            {page.MyInfinityItem}
                                        </m.MyInfinityInfoTitle>
                                    </m.MyInfinityInfoLi>
                                ))}
                            </div>
                        ))}
                    </m.MyInfinityInfoBody>
                </m.MyInfinityInfoArea>
            </m.MyInfinityBodyArea>
        </m.MyInfinityWrap>
    );
};

export default React.memo(MyInfinity);
  • react-intersection-observer 라이브러리의 useInView 훅과 이전 코드 블록에서 정의된 useMyInfinityList 커스텀 훅을 사용하여 항목 목록에 대한 무한 스크롤을 구현해 보았다.

  • MyInfinity 구성 요소는 useMyInfinityList 후크에서 반환된 data 배열을 사용하여 항목 목록을 렌더링합니다. useInView 후크는 사용자가 페이지의 보이는 부분의 끝에 도달하는 시기를 감지하는 데 사용되며 fetchNextPage 함수는 사용 가능한 경우 데이터의 다음 페이지를 로드하기 위해 호출됩니다. 'hasNextPage' 변수는 로드할 페이지가 더 있는지 확인하는 데 사용됩니다.

  • monthDatetype 변수는 useMyInfinityList 커스텀 훅의 인수로 사용되어 초기 데이터를 가져오고 변경될 때마다 useMemo 함수에서 업데이트됩니다. refetch 함수는 변수가 업데이트될 때 데이터를 다시 로드하는 데 사용됩니다.

  • 'data' 배열은 데이터의 각 페이지를 렌더링하도록 매핑되고 'inView' 변수는 사용자가 현재 페이지의 끝에 도달했는지 확인하는 데 사용됩니다. inView 변수가 true이고 사용 가능한 다음 페이지가 있고 데이터의 마지막 페이지에 10개 이상의 항목이 있는 경우 fetchNextPage 함수가 호출되어 다음 페이지를 로드합니다.

결론 및 고찰

결론적으로 react-intersection-observerreact-query를 사용하여 무한 스크롤을 구현하면 웹 사이트 소유자와 사용자에게 여러 가지 이점을 제공할 수 있습니다. 사용자 참여 및 유지, 웹사이트 성능을 개선하고 사용자에게 보다 편리한 브라우징 경험을 제공할 수 있습니다.

그러나 특히 대량의 데이터를 처리할 때 무한 스크롤을 구현하는 것도 어려울 수 있습니다. 주요 어려움 중 하나는 서버에 과부하를 주거나 사용자에게 성능 문제를 일으키지 않고 데이터의 다음 페이지를 로드할 시기를 결정하는 것입니다. 또 다른 어려움은 데이터 상태를 관리하고 데이터가 적절하게 캐시되고 업데이트되는지 확인하는 것입니다.

react-queryreact-intersection-observer를 사용하면 두 라이브러리 모두 데이터를 가져오고, 캐싱하고, 업데이트하고, 데이터의 다음 페이지를 로드할 시기를 감지하는 데 유용한 도구를 제공하므로 이러한 어려움 중 많은 부분을 완화할 수 있습니다. .

이러한 라이브러리를 사용하여 무한 스크롤을 구현하는 과정을 통해 적절한 데이터 관리 및 캐싱의 중요성과 라이브러리를 사용하여 복잡한 기능을 단순화하는 이점을 배웠습니다. 또한 무한 스크롤이 작동하는 방식과 사용자 경험을 개선할 수 있는 방법에 대해 더 깊이 이해하게 되었습니다.

전반적으로 react-intersection-observerreact-query를 사용하여 무한 스크롤을 구현하는 것은 어려울 수 있지만 궁극적으로 보람이 있습니다. 사용자에게 원활한 브라우징 경험을 제공하는 동시에 웹 사이트 성능과 사용자 참여를 향상시키는 강력하고 효율적인 방법을 제공합니다.

profile
3년차 프론트엔드 개발자입니다

0개의 댓글