본문 바로가기

토이프로젝트/programmerGround

scroll 이벤트를 활용한 React 무한 스크롤 구현(feat. throttle)

반응형

한 파일 내에서 axios로부터 받은 무한 스크롤을 구현하였습니다.

먼저 저는 상태를 지정하기 위해서 2가지 변수를 지정하였습니다.

  1. result는 현재 렌더링되는 playground 리스트를 의미합니다.
  2. item은 처음에 axios를 통해서 모든 데이터를 담을 변수입니다.
const [result, setResult] = useState<any[] | any>([]);
const [item, setItem] = useState<any[] | any>([]);

    3. fetchMoreData는 스크롤할 경우 추가적으로 데이터를 받아오는 함수입니다.

const fetchMoreData = async () =>{
       setResult(result.concat(item.slice(0, 15)));
       setItem(item.slice(15));
 };

     4. infiniteScroll

             - clientHeight : 사용자가 지금 보는 높이

             - scrollTop : 사용자가 보는 페이지와 최상단과의 차이

             - scrollHeight : 화면의 높이값

           

             - 즉 화면의 높이값 <= clientHeight + scrollTop이 성립하는 경우에 데이터를 추가한 후 렌더링을 해줍니다.

             - 저의 경우는 페이지 전체에 적용되어야 하기 떄문에 전역 객체에 이벤트를 등록해주었습니다.

 

window.addEventListener('scroll', infiniteScroll, true);

 

     5. throttle

             - 이렇게 구현하면 동작은 하지만 scroll할 때마다 데이터를 가져오기 때문에 성능 저하를 초래할 수 있습니다. 이러한 데이터를 가져오는 이벤트를 일시적으로 발생시키기 위해서 throttle을 적용해보았습니다.

             - 먼저 throttle.js라는 모듈을 만들어주었습니다. 이는 throttling을 도와주는 모듈입니다.

           

export const throttling = () => {
              let throttleCheck: any;
              
              return {
              throttle(callback: any, milliseconds: number) {
              if (!throttleCheck) {
                     throttleCheck = setTimeout(() => {
                             callback();
                             throttleCheck = false;
                     }, milliseconds);
                   }
              },
             };
 };

 

클로저 구조를 가지고 있는데 이는 throttleCheck 변수를 외부에서 접근하지 못하도록 하기 위해서 사용한 것 같습니다.

 

- 실행 순서

  1. throttleCheck를 통해서 throttle 상태가 아닐 때만 callback을 실행합니다.
  2. setTimeout은 timer id를 반환하기 때문에 호출 시점에 throttleCheck에 숫자가 할당되어 true 값으로 여겨집니다.
  3. callback의 실행이 완료되고 throttleCheck를 false로 바꾸어 다시 함수 호출이 가능한 상태로 바꿉니다.
const throttler = throttling(); throttler.throttle(fetchMoreData, 500);

 

 

반응형