기획 중인 서비스 페이지 중, 검색 페이지 (현재명 Article)의 무한 스크롤을 만들었다.

 

원래대로라면 div block 하나에 이미지 API, 이름 API, 기사 API를 하나씩 포함하는 것으로 구상했다.

그러나 이것을 무한히 복사하거나 임의로 단순 복제한다면 같은 API를 여러번 불러와야 하므로 과부하가 생길 것으로 예상했다.

 

곧장 props로 넘기려니 혼란스러워, 우선 궁극적으로는 각 데이터 매핑을 한다고 생각하고, 무한 스크롤 먼저 구현하기로 했다.

 

import React, { useState, useEffect } from 'react'
import s from '../stores/styling'

const Article: React.FC = () => {
  const [articles, setArticles] = useState<number[]>([1, 2])

  useEffect(() => {
    const handleScroll = () => {
      if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 500) {
        setArticles(prevArticles => [
          ...prevArticles,
          prevArticles.length + 1,
          prevArticles.length + 2
        ])
      }
    }

    window.addEventListener('scroll', handleScroll)
    return () => window.removeEventListener('scroll', handleScroll)
  }, [])

  return (
    <s.ArticleWrapper>
      <h1>Article</h1>
      <s.ArticleMidWrapper>
      {articles.map((article, index) => (
        <s.ArticleDiv key={index} className='article-cards'>
          테스트 {article}
        </s.ArticleDiv>
      ))}
      </s.ArticleMidWrapper>
    </s.ArticleWrapper>
  )
}

export default Article

 

1. useState를 사용하여 각 block에 넘버링을 하기로 했다.

2. useEffect 훅을 적용한다. (component 마운트 시 한 번만 수행)

 - 브라우저 창의 높이 (window.innerHeight) 와 윈도우 상단에서 현재까지 스크롤된 픽셀 (scrollY) 을 더하고,

 - 문서 전체 높이 (document.body.offsetHeight) 에서 임의로 500px을 빼서 하단에 가까운 지점을 설정한다.

 - 이 둘을 비교하여 전자가 같거나 더 크다면, 즉 현재 스크롤이 하단에 가까워졌는지 확인한다.

 

 - 위 조건을 만족한 경우, setArticles 를 호출하여 상태를 업데이트한다.

 - ...prevArticles 를 통해 기존의 articles 배열을 복사한다.

 - 기존 배열의 길이에 1과 2를 추가한다.

 

3. 이벤트가 발생할 때마다 handleScroll을 호출한다.

4. component가 언마운트 될 때 eventListener를 해제해준다. (메모리 누수 방지, component를 사용하지 않을 때 호출하지 않음)

 

+ Recent posts