본문 바로가기

사이드 프로젝트

[React 프로젝트] 무한 스크롤 도입기.. (react-intersection-observer, typescript)

프로젝트에 공통적으로 재사용 가능한 무한 스크롤 컴포넌트를 만들어보았다 

 

react-intersection-observer의 useInView

useInView는 요소가 화면에 보이는지 여부를 감지해 주는 역할을 하는데 

이 것을 활용해서 무한 스크롤 컴포넌트가 보이면 다음 페이지 api를 요청할 수 있도록 하면 된다.

 

EndLine.tsx

import { useEffect } from 'react'
import { useInView } from 'react-intersection-observer'
import styled from 'styled-components'

export default function EndLine({
  hidden = false, 
  mt = '17px',
  onShowEndPage,
}: {
  hidden?: boolean
  mt?: string
  onShowEndPage: () => void
}) {
  const { ref, inView } = useInView({
    threshold: 1, 
  })

  useEffect(() => {
    if (inView) {
      onShowEndPage()
    }
  }, [inView])
  return (
    <Line ref={ref} $mt={mt}>
      {hidden ? ' ' : 'END'}
    </Line>
  )
}

const Line = styled.div<{ $mt: string }>`
  width: 100%;
  color: #dadada;

  margin-top: ${({ $mt }) => $mt};
  margin-bottom: ${({ $mt }) => $mt};
  font-family: Pretendard-Regular;
  font-size: 15px;
  font-weight: 600;
  font-stretch: normal;
  font-style: normal;
  letter-spacing: normal;
  text-align: left;
  line-height: 18px;
  display: flex;
  place-content: center;
`

 

props 설명

- hidden : 무한 스크롤 컴포넌트가 화면에 드러날지, 혹은 화면에 드러나지 않을지 여부 => hidden인 경우는 div가 존재하기는 하나, 화면상에는 나타나지 않음

- mt : margin-top 

- onShowEndPage => 부모 컴포넌트로 조회를 요청할 props 함수

 

useInView

- ref : 관찰 하고자 하는 요소에 참조

- threshold : 화면에 얼마나 보일지를 설정 , 1로 표시 했으니 화면에 100%표시 된 경우 

- inView : 요소가 threshold에서 설정한 비율 이상으로 화면에 보이는 상태일 때 true 를 반환

 

위의 컴포넌트를 무한스크롤을 할 화면의 데이터 리스트 맨 끝에 위치 시켜주면, 

재사용이 가능하다.

 

부모컴포넌트 예시

return (
    <>
      {list?.map((item, index) => {
        return (
          <>
            <FollowItem
              mt={index === 0 ? '0px' : '16px'}
              isFollowerPage={isFollowerPage}
              key={generateRandomKey()}
              afterFollow={afterFollow}
              defaultVal={item.isFollowed} 
              item={item}
            />
          </>
        )
      })}
      <EndLine hidden={true} onShowEndPage={changePage} />
    </>
  )

 

list의 맨 마지막 단에 위치시키면 onShowEndPage요청시 chagePage 함수가 실행 되면서 

다음 페이지에 있는 데이터를 불러올것이다.

 

 

 

 

 

 

구현 하고 보니까 코드는 굉장히 간결했는데, 

처음 시도해 본 무한 스크롤이라 

방법을 찾을 때는 시간을 많이 들였던 것 같다.