[TIL] 22.05.12 프리온보딩 Day 8 - Infinite scroll(intersection-observer)

2022. 5. 13. 23:06·Education/Wanted Pre-Onboarding FE Course
반응형

드디어.. 무한 스크롤을 완성했다. 사실 깔끔하게 짜진 못한 것 같은데 그래도 기능은 잘 동작하는 중이다!

무한 스크롤 구현에는 intersection-observer을 이용했다.

 

 

영화 정보는 한 번에 10개씩 받아오고 맨 아래로 내리면 추가적으로 10개씩 받아온다.

const [movieList, setMovieList, resetMovieList] = useRecoil(movieListState) // 영화 api로 받아온 영화 정보
const [currPage, setCurrPage] = useState<number>(1) // 현재 페이지 번호
const [isLoading, setIsLoading] = useState<boolean>(false) // 로딩 중 여부
const [totalResults, setTotalResults] = useState<number>(0) // 영화 총 갯수

const pageEnd = useRef(null)

먼저 state들을 정의해주고 useRef를 이용해서 마지막 요소를 observe할 수 있도록 한다.

 

로딩 상태일 때만 Loading이 보일 수 있게 하고 해당 요소에 ref를 붙여주면 된다.

return (
    <div className={styles.search}>
      <main className={styles.searchMain}>
        {movieList.length ? (
          <ul className={styles.itemList}>
            {movieList.map((movie, idx) => {
              const key = `movie-${idx}`
              return <Item key={key} movie={movie} />
            })}
            <li className={styles.observeLi} ref={pageEnd}>
              {isLoading && 'Loading... 😊'}
            </li>
          </ul>
        ) : (
          <div>에러 메시지</div>
        )}
      </main>
    </div>
  )

 

useState안에서 intersection observer를 사용해주면 된다.

target의 isIntersecting이 true라면 (스크롤이 맨 아래 요소로 도달했으면) loadMore() 함수를 실행한다. 

useEffect(() => {
  let observer: IntersectionObserver

  if (pageEnd.current) {
    observer = new IntersectionObserver(
      async (entries) => {
        const target = entries[0]

        if (target.isIntersecting) {
          if (currPage * 10 < totalResults) { // 영화의 총 갯수보다 많이 호출되지 않도록 함.
            loadMore()
          }
        }
      },
      { threshold: 1.0 }
    )

    observer.observe(pageEnd.current) 
  }
  // eslint-disable-next-line react-hooks/exhaustive-deps
}, [totalResults])

 

loadMore()에서는 현재 페이지를 1씩 증가시켜주고, 현재 페이지가 변화할 때마다 loadMovies를 실행해 새로운 영화 데이터를 불러와준다.

// 현재 페이지가 변하면 다음 페이지의 영화를 불러옴.
useEffect(() => {
  loadMovies(currPage)
  // eslint-disable-next-line react-hooks/exhaustive-deps
}, [currPage])

// 현재 페이지 +1
const loadMore = () => {
  setCurrPage((prev) => prev + 1)
}

// 영화 정보 불러옴.
const loadMovies = async (page: number) => {
  try {
    const { data } = await getMovieListApi({
      s: searchInputVal,
      page,
    })
     if (page === 1) {
      setTotalResults(data.totalResults)
    }
     if (data.Response === 'True') {
      setMovieList((prev) => [...prev, ...data.Search])
    }
  } finally {
    setIsSubmitted(false)
    setIsLoading(true)
  }
}

 

 

👀 전체 코드

더보기

https://github.com/Seohyun-Roh/wanted_gripcorp/blob/main/src/routes/Search/index.tsx


어찌저찌 구현은 완료했지만 useEffect에서 함수 이름도 같이 넣어주면 요청이 계속 가는 경우가 생겨 어쩔 수 없이 그 줄에서만 eslint를 무시하는 옵션을 넣어주었다.

 

이틀동안 뭔가 될 것같은데 자꾸 오류가 나서 스트레스를 많이 받았는데 그래도 해결해서 다행이다 🥲

반응형

'Education > Wanted Pre-Onboarding FE Course' 카테고리의 다른 글

[TIL] 22.05.18 프리온보딩 Day 12 - React Query  (0) 2022.05.19
[TIL] 22.05.17 프리온보딩 Day 11  (0) 2022.05.18
[TIL] 22.05.11 프리온보딩 Day 7  (0) 2022.05.12
[TIL] 22.05.10 프리온보딩 Day 6 - Recoil, CRA .env 설정  (0) 2022.05.11
[TIL] 22.05.09 프리온보딩 Day 5 - TypeScript  (0) 2022.05.10
'Education/Wanted Pre-Onboarding FE Course' 카테고리의 다른 글
  • [TIL] 22.05.18 프리온보딩 Day 12 - React Query
  • [TIL] 22.05.17 프리온보딩 Day 11
  • [TIL] 22.05.11 프리온보딩 Day 7
  • [TIL] 22.05.10 프리온보딩 Day 6 - Recoil, CRA .env 설정
SH_Roh
SH_Roh
  • SH_Roh
    혼자공부끄적끄적
    SH_Roh
  • 전체
    오늘
    어제
    • 분류 전체보기 (159)
      • FE (39)
        • HTML, CSS (3)
        • Javascript (17)
        • React (11)
        • Next.js (4)
      • Network (1)
      • DevOps (4)
      • Git (1)
      • Trouble Shooting (24)
      • Algorithm (41)
        • Python (2)
        • Data Structure, Algorithm (7)
        • Problem Solving (31)
      • Education (23)
        • Elice AI Track (4)
        • Wanted Pre-Onboarding FE Co.. (19)
      • TIL (25)
      • Etc. (1)
        • 회고 (1)
        • 그냥저냥 (0)
  • 링크

    • Github
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
SH_Roh
[TIL] 22.05.12 프리온보딩 Day 8 - Infinite scroll(intersection-observer)
상단으로

티스토리툴바