본문 바로가기
Frontend

[React] Scroll event를 이용하여 Infinite scroll 구현하기

by roses16 2023. 7. 2.

Infinite scroll을 구현하는 데에는 여러 방법이 있는데 아래 예시는 그 중 Scroll event를 이용하여 Hook을 만들었다.


  1. 현재 유저가 보고있는 View의 위치와 Document의 전체 길이를 비교하여 View가 Document의 가장 하단인지 확인한다.
  2. 가장 아래일 때 isFetching에 True를 세팅한다.
    ※ lodash의 throttle 함수를 이용하여 "Scroll" event가 과도하게 호출되는 것을 막는다.
  3. isFetching이 변경되면 이를 의존성 배열로 갖는 useEffect 함수가 실행된다.
    useEffect 함수 내에서는 isFetching이 True일 경우 매개변수로 전달된 Callback함수를 실행한다.
  4. Callback 함수는 Element를 추가하는 기능을 수행한다.
// useInfiniteScroll.js

import { useState, useEffect } from "react"
// scroll event가 연속적으로 발생하지 않도록 throttle을 사용하여 최적화한다. lodash package 설치가 필요하다.
import { throttle } from "lodash";

const THROTTLE_WAIT = 300;

export default function useInfiniteScroll(fetchCallback){
    const [isFetching, setIsFetching] = useState(false);

    // 유저가 보고있는 view가 document의 제일 아래인지 체크하는 함수
    // window.innerHeight : 뷰포트 높이를 px단위로 나타낸다.
    // document.documentElement.scrollTop : 스크롤의 위치를 px단위로 나타낸다. 가장 위는 0 아래로 내려갈수록 값이 커진다.
    // document.documentElement.offsetHeight : border를 포함한 박스의 길이
    const handleScrollThrottle = throttle(() => {
        if(window.innerHeight + document.documentElement.scrollTop >= document.documentElement.offsetHeight){
            setIsFetching(true);
        }
    }, THROTTLE_WAIT);
	
    // Scroll Eventlistener를 등록하여 scroll event가 발생하면 handleScrollThrottle함수를 통해 유저의 view 위치를 계산한다. 
    useEffect(() => {
        window.addEventListener('scroll', handleScrollThrottle);
        return () => {
            window.removeEventListener('scroll', handleScrollThrottle);
        }
    }, []);
    
    // isFetching값이 true가되면 매개변수로 전달받은 콜백함수를 실행한다.
    useEffect(() => {
        if(!isFetching) {
            return;
        }
        fetchCallback();
    }, [isFetching])

    return [isFetching, setIsFetching]
}

 


📌 출처