무한스크롤 의 구현방식은 여러가지 입니다

(infinite-scroll-component / intersection-observer / 스크롤 위치 감지 등)

저는 스크롤 위치가 ‘scrollHeight’ 의 맨 끝 지점(100) 에 왔을때
서버에서 데이터를 10개씩 추가로 불러오는 방식을 구현해봤습니다


1. 서버에서 데이터 받아오기

1-1. fetch 또는 Axios 를 이용하여 서버에서 데이터를 받아오고
1-2. useState 빈배열을 ‘두개 생성’ 합니다
1-3. 배열 하나는 데이터를 보여주고
1-4. 배열 하나는 남은 데이터를 저장하는 용도입니다


2. 저장소에서 데이터 꺼내오기

👆 스크롤이 목표위치 에 도달했을때 서버에서 데이터를 추가로 받아오는 함수

2-1. 저장된 데이터가 0개 가 아닐경우 실행
2-2. 배열에 담긴 값을 10개씩 꺼내서 출력 (몇개씩 출력할지는 셋팅)


3. 스크롤 위치 감지

👆 스크롤의 위치를 감지하고 조건에 만족하면 데이터를 꺼내오는 함수를 실행

scrollTop + clientHeight >= scrollHeight


4. 스크롤 이벤트 등록 & 삭제

스크롤 위치를 감지할때마다 이벤트를 실행하고 & 삭제

addEventListener / removeEventListener


5. 무한스크롤 구현

10개씩 데이터를 불러오는 무한스크롤


무한스크롤 구현에 성공한 코드 👇

const [poolList, setPoolList] = useState([]);
const [savePoolList, setSavePoolList] = useState([]);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
  const poolData = () => {
    setIsLoading(true); // 데이터를 불러오는중에는 로딩중 표시
    fetch(
      "https://gateway.pinata.cloud/ipfs/QmNYomgBofjWrYkkdWQA2KTqkv8HxMe3iwFsYScGCkX16K"
    )
      .then((res) => res.json())
      .then((list) => {
        setPoolList(list.slice(0, 10)); // 서버에서 데이터를 10개만 보여주고
        setSavePoolList(list.slice(10)); // 보여주는 데이터 10개 제외한 나머지는 빈배열에 저장
        setIsLoading(false); // 데이터를 다 불러왔으면 로딩중 끝
      });
  };
  poolData();
}, []);

const poolSaveData = async () => {
  // 서버에서 데이터를 추가로 받아오는 함수 (비동기처리)
  if (savePoolList.length !== 0) {
    // useState 배열에 저장된 길이가 0이 아닐경우 실행
    setIsLoading(true); // 데이터를 불러오는중에는 로딩중 표시
    setTimeout(() => {
      // 바로 실행하지말고 1초 뒤에 실행시키기
      setPoolList([...poolList, ...savePoolList.slice(0, 10)]);
      // 서버에 담긴 값, 저장된 데이터 10개 꺼내기
      setSavePoolList(savePoolList.slice(10)); // 저장된 데이터 10개 출력
      setIsLoading(false); // 데이터를 다 불러왔으면 로딩중 끝
    }, 1000); // 👉 1초
  }
};

const infiniteScroll = useCallback(() => {
  //스크롤 높이를 감지해서 👉 조건에 만족하면 poolSaveData 함수 호출
  let scrollHeight = Math.max(
    document.documentElement.scrollHeight,
    document.body.scrollHeight
  );
  let scrollTop = Math.max(
    document.documentElement.scrollTop,
    document.body.scrollTop
  );
  let clientHeight = document.documentElement.clientHeight;

  scrollHeight -= 100; // 스크롤이 맨 끝 지점(100)에 왔을때

  if (scrollTop + clientHeight >= scrollHeight && isLoading === false) {
    poolSaveData();
  }
}, [isLoading]);

useEffect(() => {
  window.addEventListener("scroll", infiniteScroll, true); // 스크롤 이벤트 등록
  return () => window.removeEventListener("scroll", infiniteScroll, true); //스크롤 이벤트 삭제
}, [infiniteScroll]);

참고 했던 사이트 🖥