무한스크롤 구현하기 2편

미누도 개발한다·2021년 8월 5일
0

리액트

목록 보기
8/11

스로틀을 사용하였다. useCallback 을이용해서 스로틀함수를 생성하였으며, dependecy를 추가해서,dependency에따라 스로틀함수를 재생성했고,
클린업 함수를 통해 과거시점의 스크롤 이벤트는 remove해주고 , 현재시점의 스크롤이벤트를 등록해주었다. 그렇게해야 스로틀 함수에서 현재 렌더링시점의 state값을 참조 할 수 있다.

또한 메모리 최적화를 위해 throttle.cancel()을 사용해서, 이벤트 큐에 등록되어있는 스로틀함수중에서 과거시점에 등록된 스로틀함수들을 모두 지워주었다.

  • 구현코드
import React,{Fragment,useEffect,useCallback,useRef} from 'react'
import _ from 'lodash';

import InfiniteSpinner from './InfiniteSpinner';

function InfinityScroll(props) {
    const dependency = [props.children,props.callNext,props.isNext,props.isLoading];
    
    const _throttle = _.throttle(()=>{
        
        if(props.isLoading){
            return
        }
        let scrollHeight= document.documentElement.scrollHeight;
        let scrollTop = document.documentElement.scrollTop
        let clientHeight = document.documentElement.clientHeight;
        
        if(scrollHeight-scrollTop-clientHeight < 300){
            props.callNext(); // 데이터 fetch로직
        } 
        
    },1000);

    const throttle = useCallback(_throttle,dependency); 
    
    useEffect(()=>{
        
        if(props.isLoading){ 
            return;
        }
        window.addEventListener('scroll', throttle);

        return ()=> {
            window.removeEventListener('scroll',throttle);
            throttle.cancel();
        }
    },dependency);


    return (
        <Fragment>
            {props.children}
            {props.isNext ? <InfiniteSpinner/>:null }
        </Fragment>
    )
}

InfinityScroll.defaultProps = {
    children:null,
    callNext:()=>{},
    isNext:null,
    isLoading:false
}
export default InfinityScroll

위에 제가 사용한 의존성은, 리덕스 스토어의 데이터들 입니다.
props.isNext: 리덕스와 통신하여 다음 fetch할 데이터가 있는지 저장해놓은 리덕스 스토어 데이터
props.isLoading: 현재 데이터 fetch 중인지를 의미
props.callNext: 파이어스토어에 접근하는 함수를 호출하는 함수



  • 하단 스크롤 인식하기
 if(scrollHeight-scrollTop-clientHeight < 300){
            props.callNext();
        } 

scrollHeight-scrollTop-clientHeight 을 통해 현재 스크롤화면이 브라우저의 맨하단에서 얼만큼 떨어져 있는지 계산해준다. 맨 아래 남은 px이 300px 이하가되면 바닥에 닿았다고 판단하고 다음 데이터를 fetch 요청한다.

profile
빨리 가는 유일한 방법은 제대로 가는 것이다

0개의 댓글