React로 무한 스크롤 구현하기

3년 전·수정됨
React로 무한 스크롤 구현하기

이번에는 react-intersection-observer를 이용해서 무한 스크롤을 구현하는 방법을 알아가보도록 하겠습니다.

들어가기 앞서

image

많은 콘텐츠를 효과적으로 보여줄 수 있는 대표적 UI 에는 무한 스크롤, 페이징 이 있습니다.

PC에서는 페이징, 모바일에서는 무한 스크롤 UI 가 각각 더 사용자에게 편하게 다가옵니다. 하지만 최근에는 반응형 페이지를 통해서 PC와 모바일 모두 커버하는 경우가 많기 때문에 이번에는 무한 스크롤 을 함께 구현해보도록 하겠습니다.

구현

무한 스크롤을 구현하는 방법은 여러가지가 있겠지만, 가장 확실한 방법은 마지막 요소가 사용자에게 보이면 다음 데이터를 불러오는 방법이 있습니다.
react-intersection-observer 라이브러리를 사용하면 위와 같은 방법을 보다 쉽게 구현할 수 있습니다.

설치

yarn add react-intersection-observer

또는

npm i react-intersection-observer

사용 방법

import React from "react" import { useInView } from "react-intersection-observer" const App = () => { const [ref, inView] = useInView() return ( <div ref={ref}> Element {inView.toString()} </div> ) } export default App

ref 를 div에 걸어주면 해당 요소가 보이면 inView가 true 로, 안 보이면 false로 자동으로 변경됩니다.

직접 보기

예제

// App.js import React, { useState, useEffect, useCallback } from "react" import { useInView } from "react-intersection-observer" import axios from "axios" const App = () => { const [items, setItems] = useState([]) const [page, setPage] = useState(1) const [loading, setLoading] = useState(false) const [ref, inView] = useInView() // 서버에서 아이템을 가지고 오는 함수 const getItems = useCallback(async () => { setLoading(true) await axios.get(`${Your Server Url}/page=${page}`).then((res) => { setItems(prevState => [...prevState, res]) }) setLoading(false) }, [page]) // `getItems` 가 바뀔 때 마다 함수 실행 useEffect(() => { getItems() }, [getItems]) useEffect(() => { // 사용자가 마지막 요소를 보고 있고, 로딩 중이 아니라면 if (inView && !loading) { setPage(prevState => prevState + 1) } }, [inView, loading]) return ( <div className="list"> {items.map((item, idx) => ( <React.Fragment key={idx}> {items.length - 1 == idx ? ( <div className="list-item" ref={ref}> {item.content} </div> ) : ( <div className="list-item"> {item.content} </div> ) </React.Fragment> ))

간단하게 예제를 만들어 보았습니다. 차근차근 코드를 보도록 하죠.

getItems 함수는 page 가 바뀔 때 마다 재생성 되는 함수입니다. 이 함수를 useEffect 에 대괄호 안에 넣어 getItems 함수가 바뀔 때 마다 getItems 를 실행하도록 하였습니다.

결론적으로 page 가 바뀔 때 마다 서버에 정보를 요청합니다. 다음 페이지를 불러오기 위해서는 page 만 증가시키면 바로 다음 페이지에 관한 정보를 받아옵니다.

두 번째 useEffectinView 가 바뀔 때마다 inViewtrue 이고, 로딩중이 아니라면 page 를 증가시킵니다.

마치며

스크롤을 계산하여 데이터를 불러오는 무한 스크롤 방식은 아이폰에서의 스크롤 이벤트가 다르게 적용되어 생각보다 까다로운 부분들이 많았는데 이 글을 보고 react-intersection-observer 를 사용하여 보다 쉽게 구현할 수 있었으면 좋겠습니다.

댓글 2
권용빈
권용빈3년 전
유용한 무한스크롤 잘보고가요 ㅎㅎ
김펭구
김펭구1년 전
덕분에 쉽게 구현할수있었어요 고마워요 ㅎㅎ