[다독다독] 무한 스크롤 구현하기

KINA KIM·2022년 5월 28일
0

무한 스크롤

현재 다독다독의 도서 검색 기능은 API에 파라미터로 책의 개수 받아 일정 개수의 도서만 검색이 가능하기 때문에 책 탐색에 한계가 있다.

원하는 책을 찾을 때까지 스크롤을 내리다 뷰포트의 최하단에 닿는 순간 다음 책들을 불러오기 위해 인피니트 스크롤이 필요하다.

어떻게 할 것인가?

useEffect를 사용하여 뷰포트의 최하단에 닿으면 pageNums state값을 ++ 해주면서 API를 다시 호출하는 식으로 구현을 해볼 예정이다. 또한 다독다독의 책 검색 리스트에는 이미지도 포함되어 있기 때문에 트래픽을 최소화하기 위해 img 태그에 lazy load 속성을 추가한다.

구현

첫 번째로 도서 API 호출쪽을 수정했다. isScroll을 파라미터로 받아 true면 불러올 pageNum을 1씩 추가해주면서 API를 재호출하여 기존 books 리스트에 붙여넣고, false면 새로운 검색어를 입력받은 것으로 인식하여 books와 pageNum을 초기화한다.

  // 도서API 호출
  const FetchBooks = async(keyword, isScroll) =>{
    let params = {
      query : keyword,
      page : pageNum,
    }
    if (isScroll){
      setPageNum(pageNum+1)
      params = {...params, page: pageNum}
    } else {
      setBooks([])
      setPageNum(1)
    }
    const response = await BookService.searchBooks(params)
    setBooks([...books, ...response.data.documents])
  }

두 번째로는 검색한 도서가 보여지는 컴포넌트인 SearchResult를 수정했다. 스크롤되어 올라간 만큼의 높이(scrollTop) + 현재 보여지는 요소의 높이(clientHeight)이 요소의 전체 높이(scrollHeight)보다 크거나 같으면 뷰포트의 끝에 닿았다고 인식하여 FetchBook을 호출하는 형식이다.
(즉, 스크롤을 내려서 이동한 높이와 요소의 전체 높이가 같아지면 스크롤의 최하단까지 내려왔다고 인식함)

scrollTop


(출처: http://lab.naminsik.com/158)


(출처: https://blogpack.tistory.com/706)

clientHeight, scrollHeight

const infiniteScroll = () =>{
    const scrollHeight = document.querySelector('.content').scrollHeight
    const scrollTop = document.querySelector('.content').scrollTop
    const clientHeight = document.querySelector('.content').clientHeight
    if (scrollTop + clientHeight >= scrollHeight) {
        props.FetchBooks(params.keyword, true)
    }
}
useEffect(() => {
    document.querySelector('.content').addEventListener('scroll', infiniteScroll)
    return () =>  document.querySelector('.content').removeEventListener('scroll', infiniteScroll)
})
    })

LazyLoading은 img 태그에 loading='lazy'를 추가했다. 사파리에서는 작동하지 않는다고 하니 추후에 보완할 예정이다.

<img src={props.book.thumbnail} loading='lazy'></img>

0개의 댓글