#28. 무한 스크롤 (infinite scroll) 구현

박현재·2020년 11월 29일
0

무한스크롤 기능 구현을 위해서 Query String을 이용한 Pagination 기능을 알아야 합니다.

Pagination

백엔드에서 가지고 있는 데이터는 많고, 그 데이터를 한 화면에 전부 보여줄 수 없는 경우에 사용됩니다. Pagination은 프론트엔드, 백엔드 양쪽에서 모두 구현해야하며, 프론트엔드에서 현재의 위치(Offset)와 추가로 보여줄 컨텐츠의 수(Limit)를 백엔드에 전달합니다. 백엔드에서는 그에 해당하는 데이터를 끊어서 보내주는 방식으로 구현하게 됩니다.

`http://xx.xx.xx.xx:8000/ootds?offset=0&limit=10` 다음의 주소를 해석하면, offset은 데이터가 시작하는 위치를 알려주고, limit은 한 페이지에 보여줄 데이터의 수를 나타냅니다. ootds뒤에 ? 기호는 url에서 한 번만 쓸 수 있으며 Quary String의 시작임을 알립니다.
제가 접근한 방식은 2가지인데, 둘 다 코드를 통해 살펴보겠습니다.
첫 번째는, 스크롤 할 때마다 scroll event를 발생시키는 단점이 있지만, 직접 DOM에 접근하여 스크롤 높이 값, 화면의 상단, 하단의 위치를 설정해서 설정한 target지점에 도달했을 때 fetch하여 데이터의 일부분을 가져오는 방법입니다.

먼저, 클래스 밖에 다음 값들을 선언해 줬습니다.
const API = http://xx.xx.xx.xx:8000;
const LIMIT = 10;
state에는 offSet값을 0으로 선언해줬습니다.
class Main extends Component {
  constructor() {
    super();
    this.state = {
      offSet: 0,
      isLoading: false,
    }
  }

첫 화면은 데이터를 0부터 10까지 불러오도록 설정했습니다. 그리고 offSet은 실행 될 때마다, 10씩 증가합니다.
componentDidMount() {
    window.addEventListener("scroll", this.infiniteScroll);
    fetch(`${API}/ootds?offset=${this.state.offSet}&limit=${LIMIT}`)
    .then((res) => res.json())
    .then((res) => 
    this.setState({
      cards: res.ootd_list,
      offSet: this.state.offSet + LIMIT,
    })
  }
  
// 해당 화면에서의 높이 값과, 화면의 상단 값, 전체의 높이 값을 통해
 infiniteScroll = () => {
   const scrollHeight = Math.max(
     document.documentElement.scrollHeight,
     document.body.scrollHeight
     );
   const scrollTop = Math.max(
     document.documentElement.scrollTop,
     document.body.scrollTop
    );
  const clientHeight = document.documentElement.clientHeight;
  if(scrollTop + clientHeight === scrollHeight) {
    fetch(`${API}/ootds?offset=${this.state.offSet}&limit=${LIMIT}`)
    .then((res) => res.json())
    .then((res) => {
      this.setState({ isLoading: true });
      this.setState({
        cards: this.state.cards.push(res),
        offSet: this.state.offSet + LIMIT,
      });
      this.setState({ isLoading: true });
      setTimeout(() => {
      this.setState({ isLoading: false });
      }, 350);
   }
   );
   }
};

스크롤 이벤트를 이용하여 무한스크롤을 구현하려고 할 경우 발생하는 문제
개발자도구의 콘솔 창에 다음을 입력한 뒤, scroll 해보시면 알 수 있습니다!!

window.addEventListener('scroll', function() {
  return console.log('scroll');
});

따라서 선택한 방법은 라이브러리를 이용하는 것이었습니다!
무한스크롤 라이브러리
Quary String을 이용한 Pagination 하는 것은 같았지만, Event 발생을 덜 시킬 수 있어서 백엔드와의 통신에 과부하를 줄일 수 있었습니다.

  loadFunc = () => {
    fetch(`${API}/ootds?offset=${this.state.offSet}&limit=${LIMIT}`)
    .then((res) => res.json())
    .then((res) => {
      this.setState({
      cards: [...this.state.cards, ...res.ootd_list],
      offSet: this.state.offSet + LIMIT,
    });
    })
  }
  
render() {
  return (
  <InfiniteScroll
      pageStart={0}
      loadMore={this.loadFunc}
      hasMore={true || false}
      loader={<div className="loader" key={0} />}
      useWindow={false}
    >
    
    (여기에 화면에 띄울 data를 넣습니다)
    <Main />
  
  </InfiniteScroll>
  )
}
profile
바로 하자, Right Now!

0개의 댓글