무작정 만들어 본 infinite scroll in react

Infinite scroll

Start

프로젝트 중 한방에 나오는 것 보다 스크롤 내릴 때 나오는게 더 예쁠 것 같다는 생각이 들어서

급하게 무한 스크롤을 만들어 보았다.

Plan

만들기 전에 알아야 할 것은

  1. 전체 div 스크롤 높이
  2. 눈에 보이는 높이
  3. 현재 위치

이 세개를 알아야하는게

  1. 스크롤이 내려갈 때 위치를 확인
  2. 현재 위치 - 전체 div 스크롤 높이 === 눈에 보이는 div 높이
  3. 데이터를 추가해 줌

Code

아래 코드는 서버와 통신하기 전 코드입니다.

  const handleScroll = (e) => {
    console.log(e.currentTarget.scrollHeight, '스크롤높이');
    console.log(e.currentTarget.clientHeight, '클라이언트높이');
    console.log(e.currentTarget.scrollTop, '스크롤탑');

    const { scrollTop, clientHeight, scrollHeight } = e.currentTarget;
    if (scrollHeight - scrollTop === clientHeight) {
      setPage((prev) => prev + 1);
      console.log('페이지 업');
    }
  };

  useEffect(() => {
    //여기서 계속 추가를 해줘야함
    const listSliceLength = 9;
    const loadData = async () => {
      //추후 서버와 통신하여 데이터를 가져오는 부분
      setIsLoading(true);
      let remainder = state.ClothesData.slice(listSliceLength);
      let list = state.ClothesData.slice((page - 1) * listSliceLength, page * listSliceLength);
      console.log('데이터 가져오기');
      console.log('나머지', remainder);
      console.log('리스트', list);

      //9개를 뽑기전에 전체 길이가 9 보다 작은 경우
      // 9보다 많은 경우
      if (remainder.length >= 12) {
        setData((prev) => [...prev, ...list]);
      } else {
        list = state.ClothesData.slice(0, state.ClothesData.length);
        setData((prev) => [...prev, ...list]);
      }
      setIsLoading(false);
    };
    loadData();
  }, [page]);

라는 코드를 만들 수 있음

비동기 처럼 보이기 위해 임시로 setTimeout 설정

  useEffect(() => {
    //여기서 계속 추가를 해줘야함
    const listSliceLength = 9;
    const getData = () => {
      setTimeout(() => {
        let remainder = state.ClothesData.slice(listSliceLength);
        let list = state.ClothesData.slice((page - 1) * listSliceLength, page * listSliceLength);
        console.log('데이터 가져오기');
        console.log('나머지', remainder);
        console.log('리스트', list);

        //9개를 뽑기전에 전체 길이가 9 보다 작은 경우
        // 9보다 많은 경우
        if (remainder.length >= 12) {
          setData((prev) => [...prev, ...list]);
        } else {
          list = state.ClothesData.slice(0, state.ClothesData.length);
          setData((prev) => [...prev, ...list]);
        }
        setIsLoading(false);
      }, 1000);
    };
    const loadData = async () => {
      setIsLoading(true);
      getData();
      // setIsLoading(false);
    };
    loadData();
  }, [page]);

Result

좋은 웹페이지 즐겨찾기