본문 바로가기
React

[React + TS] 무한스크롤 구현하기

by 1two13 2023. 5. 23.
728x90
반응형

기업과제를 진행하면서 무한 스크롤을 적용시켰다. 

 

검색어를 입력하면 그에 따른 추천 검색어들이 드롭다운에 보여지게 되는데, 처음에는 10개가 노출되고, 추천 검색어가 10개 이상이면 무한스크롤을 사용해서 추가 데이터(10개)를 계속해서 화면에 보여주는게 구현 목표였다. 


스크롤 바가 마지막 컨텐츠를 보여주는 시점에 추가적인 데이터를 제공할 수 있도록 구현했다. 

 

마지막 컨텐츠를 보여주는 시점은 아래와 같다. 

스크롤바를 제외한 컨텐츠 높이 + 스크롤된 거리 >= 스크롤바를 포함한 전체 높이 

출처: https://velog.io/@hyeon930/%EB%AC%B4%ED%95%9C-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EB%A7%8C%EB%93%A4%EA%B8%B0-Throttling

 

컨텐츠 높이와 스크롤된 거리가 스크롤바를 포함한 전체 높이보다 크거나 같을 때 스크롤을 끝까지 완료한 것이고, 마지막 컨텐

츠가 보이는 시점이 되는 것이다. 


위의 내용을 바탕으로 바로 코드를 작성해도 되지만, 문제가 있다. 

바로 스크롤을 움직일 때마다 함수가 실행되기 때문이다. 

 

이러한 문제점을 해결하기 위해 useThrottle 커스텀 훅을 생성했다. 

 

throttle은 일정 시간동안 함수 호출을 막기 위해 사용하는 프로그래밍 기법이다. 

// src/hooks/useThrottle.ts

import { useRef } from 'react';

const useThrottle = <T extends any[]>(callback: (...args: T) => void, timeout: number) => {
  const timer = useRef<ReturnType<typeof setTimeout> | null>(null);
  return (...args: T) => {
    if (!timer.current) {
      timer.current = setTimeout(() => {
        callback(...args);
        timer.current = null;
      }, timeout);
    }
  };
};

export default useThrottle;

timer.current 값이 null인 경우에만 새로운 타이머를 설정하고, timeout 시간이 경과하면 콜백함수를 실행하도록 코드를 작성했다.

그리고 콜백함수가 실행된 이후 timer.current 값을 다시 null로 초기화하여 다음 실행을 위해 타이머를 재설정하는 코드를 작성했다.


생성한 커스텀 훅을 사용하여 onScroll 이벤트가 발생할 때의 코드를 작성했다.

// src/components/Dropdown.tsx

const Dropdown = () => {
  const [isLoading, setIsLoading] = useState(false);
  const { searchedData, setSearchedData } = useContext(ContextList);

  const onScrollDropdown = async (e: React.UIEvent<HTMLDivElement>) => {
    if (result.length >= total) return;

    const target = e.target as HTMLDivElement;
    const { scrollHeight, scrollTop, clientHeight } = target;

    if (clientHeight + scrollTop >= scrollHeight) {
      await getMoreCommendData();
    }
  };

  const throttleScroll = useThrottle<[React.UIEvent<HTMLDivElement>]>(onScrollDropdown, 700);
}
// return 코드

<div className="dropdown-container" onScroll={throttleScroll}></div>

useThrottle 커스텀 훅을 생성하여 최적화시키는 방법을 학습했고, 무한 스크롤을 구현하는 경험을 가졌다. 

무한스크롤을 직접 컨텐츠 높이를 계산하여 적용하는 방법 말고도 더 있을 거 같은데, 추가적인 방법도 궁금하다. 

 

 

 


질문이나 잘못된 점은 댓글로 남겨주세요 :)💖

728x90
반응형

댓글