Infinite scroll을 구현하는 데에는 여러 방법이 있는데 아래 예시는 그 중 Scroll event를 이용하여 Hook을 만들었다.
- 현재 유저가 보고있는 View의 위치와 Document의 전체 길이를 비교하여 View가 Document의 가장 하단인지 확인한다.
- 가장 아래일 때 isFetching에 True를 세팅한다.
※ lodash의 throttle 함수를 이용하여 "Scroll" event가 과도하게 호출되는 것을 막는다. - isFetching이 변경되면 이를 의존성 배열로 갖는 useEffect 함수가 실행된다.
useEffect 함수 내에서는 isFetching이 True일 경우 매개변수로 전달된 Callback함수를 실행한다. - 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]
}
📌 출처
'Frontend' 카테고리의 다른 글
[React] Redux Dev Tools, Development server 에서만 실행되게 설정하기 (0) | 2023.07.02 |
---|