티스토리 뷰

반응형

 

React 무한 스크롤 로딩 구현하기
React 무한 스크롤 로딩 구현하기

React에서 데이터 리스트를 스크롤만 하면 추가로 로딩이 되게 하는 방법 중 대표적인 방법 중 하나가 IntersectionObserver를 활용하는 방법이다.

동작 원리를 간단하게 설명하면 리스트 맨 끝에 UI상으로 비어있는 엘리멘트를 렌더링하고 IntersectionObserver을 이용하여 이 엘리멘트가 화면상에 노출되는 순간 데이터를 추가로 조회하는 로직을 호출하는 것이다.

예시

import React, { useEffect, useRef, useState } from "react";

const InfiniteScroll: JSX.Element = ({ loadMore } : { loadMore: () => void }) => {
    const loaderRef = useRef<HTMLDivElement>(null);
    const [isLoading, setIsLoading] = useState(false);

    useEffect(() => {
        const observer = new IntersectionObserver(
            (entries: IntersectionObserverEntry[]) => {
               /**
                * 전달된 엔트리 배열에서 첫 번째 엔트리(div element)를 가져와 해당 엔트리가
                * 화면에 보이는지(isIntersecting)와 현재 로딩 상태(isLoading)를 확인
                */
                const firstEntry = entries[0];
                if (firstEntry.isIntersecting && !isLoading) {
                    setIsLoading(true);
                    loadMore();
                }
            },
            { threshold: 1 }
        );

        if (loaderRef.current) {
            observer.observe(loaderRef.current);
        }

        /** unmount 될 때 observe 제거 */
        return () => {
            if (loaderRef.current) {
                observer.unobserve(loaderRef.current);
            }
        };
    }, [isLoading, loadMore]);

    return (
        <div>
            <div style={{ height: "1000px", overflow-y: "scroll" }}>
                {/** IntersectionObserver가 observe 하고있는 엘리멘트 */}
                <div ref={loaderRef}>
                    {/** 로딩 indicator */}
                    {isLoading && <div>Loading...</div>}
                </div>
            </div>
        </div>
    );
};

위 예시에서 threshold 옵션은 intersection을 감지하는 기준을 설정하는 옵션이다. 0부터 1까지의 숫자로 지정할 수 있으며, 기본값은 0이다. 0일 경우에는 요소가 뷰포트의 어떤 부분이라도 보이면 콜백 함수가 호출된다. 1일 경우에는 요소가 완전히 뷰포트에 보일 때만 콜백 함수가 호출된다.

예를 들어 { threshold: 0.5 }로 설정하면 요소가 뷰포트의 절반 이상 보일 때 콜백 함수가 호출되고, { threshold: 1 }로 설정하면 요소가 완전히 뷰포트에 보일 때만 콜백 함수가 호출된다.

반응형

'React와 NextJS' 카테고리의 다른 글

iOS에서 input의 focus zoom 막는 방법  (1) 2024.10.28
redirect 와 rewrite  (0) 2024.10.26
NextPage 타입이란?  (0) 2024.10.24
default props란?  (0) 2024.10.23
NextJS에서의 이미지 preload  (0) 2024.10.22
Total
Today
Yesterday
반응형