페이지네이션 포스팅 한 김에 성격이 비슷한 무한스크롤도 정리를 해본다!

무한스크롤은 굉장히 어려울 것 같았는데, pagination을 하고나니 의외로 쉬웠다. 둘의 차이점은 setState에 있다.

pagination은 불러온 데이터를 그대로 setState()에 넣어 변경하지만 infinite scroll은 처음에만 그대로 넣고, 그 후에는 전개연산자(spread operator)를 이용해서 기존의 state에 더해서 변경하는 방식이다.

이를 구현하는데에는 post로 정보를 요청할 때 단 한개의 boolean 속성만 추가하면 된다.

scroll event는 당연히 구현하는데, react에서 event listener를 추가하는건 처음이라 조금 헤맸는데, pure js에서 한 것과 똑같았다.

먼저 이번에도 infinite를 구현하는 infinite.jsx와 그를 불러오는 infiniteLanding.jsx로 나뉜다.

infinite.jsx

  
import React, {useEffect, useState} from 'react'
import Card from '../utils/card/card';

const Infinite = ({posts, fetching, fetchMoreData}) => {

  const [postInfo, setPostInfo] = useState([]);

  useEffect(() => {
    setPostInfo(posts);
  }, [posts])

  const handleScroll = () => {
    const scrollHeight = document.documentElement.scrollHeight;
    const scrollTop = document.documentElement.scrollTop;
    const clientHeight = document.documentElement.clientHeight;

    if(scrollTop + clientHeight >= scrollHeight && fetching === false) {
fetchMoreData();
}
    }

  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
      return () => {window.removeEventListener('scroll', handleScroll)
}
  })
    return (
      <div>
        { postInfo && postInfo.map((post, idx) => (
           <Card key={idx} listInfo={post} />
        ))}
      </div>
  )
}

export default Infinite

설명을 길게 해야하는데 밥이 배달와버렸다. 일단 코드를 모두 올리고 다음에 다시 부연설명 해야겠다.

일단 여기서 중요한 점은 postInfo의 값이 들어와있는 상태를 체크하기 위해 postInfo &&를 먼저 조건으로 주었다는 것이고,

useEffect에서 scroll event를 더하는 것이다.

infiniteLanding.jsx

import React, {useState, useEffect} from 'react'
import axios from 'axios'
import Infinite from './sections/infinite'

const InfiniteLanding= () => {

  const [listInfo, setListInfo] = useState([]);
  const [skip, setSkip] = useState(0);
  const [limit, setLimit] = useState(10);
  const [fetching, setFetching] = useState(false);

  useEffect(() => {

    const body = {
      skip: skip,
      limit: limit,
    };
    getData(body)
    }, [])

  const getData = (body) => {
    axios.post("/api/url", body)
      .then( res => {
         if(body.loadMore) setListInfo([...listInfo, ...res.data.listInfo]);
         else setListInfo(res.data.listInfo)
           })
      .catch(err => alert("글을 가져오는데 실패 했습니다.");)
  }

  const fetchMoreData = () => {
    setFetching(true);
    let tmpSkip = skip + limit
    let body = {
      skip: tmpSkip,
            limit: limit,
            filters: filters,
            loadMore: true
        };

        getData(body);
        setSkip(tmpSkip);
        setFetching(false);
    }


    return (
      <div>
        <h2>TITLE</h2>
      <div>
        <Infinite posts={listInfo} fetchMoreData={fetchMoreData} fetching={fetching}/>
      </div>
    )
}

export default InfiniteLanding

아 오늘 하필 국수라서 빨리 안먹으면 금방 불것 같다..

다음에 꼭 이어서 정리해야겠다

일다 이렇게 하며 구현도ㅣㄴ다!

6 thoughts to “React – Infinite Scroll, 무한 스크롤 구현하기

  • 국수는맛있어

    국수는 못참죠! 글 감사합니다 ㅎ

    응답
    • soae0923

      방문해주셔서감사합니다~

      응답
  • 어렵다..리액

    보고 따라할려고했는데 어렵네요 함수형으로 작성할까햇는데… api따는거 분리하고.

    응답
  • 미나

    다급함이 느껴지는 마지막줄ㅋㅋㅋ 감사합니다!

    응답
  • :)

    감사합니다! 많은 도움 됐습니다!!

    응답
  • 감사합니다 많은 도움 됐습니다! 🙂

    응답

Leave a comment

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다