React.js에 무한 스크롤을 추가하는 방법

웹사이트나 앱에서 스크롤을 내릴 때마다 콘텐츠가 계속 로딩되는 것을 본 적이 있으신가요? 이를 ‘무한 스크롤’이라고 합니다.

무한 스크롤은 방대한 양의 정보를 효율적으로 탐색할 수 있도록 도와주는 널리 사용되는 기술입니다. 특히 모바일 환경에서 사용자 경험을 한층 부드럽게 만들어주는 효과가 있습니다.

React에서는 다양한 방식으로 무한 스크롤을 구현할 수 있습니다. 그 중 하나는 ‘react-infinite-scroll-component’와 같은 라이브러리를 활용하는 것입니다. 이 라이브러리의 컴포넌트는 사용자가 페이지 하단에 도달할 때마다 특정 이벤트를 발생시킵니다. 이 이벤트를 감지하여 추가 콘텐츠를 로드할 수 있습니다.

React에서 무한 스크롤을 구현하는 또 다른 방법은 내장된 기능을 이용하는 것입니다. 예를 들어, ‘componentDidMount’ 함수는 React 컴포넌트가 처음으로 마운트될 때 실행됩니다.

이 함수를 사용하여 초기 데이터 배치를 로드한 후, 사용자가 스크롤할 때 ‘componentDidUpdate’ 함수를 활용하여 후속 데이터를 로드할 수 있습니다.

React Hook을 사용해서도 무한 스크롤 기능을 추가할 수 있습니다.

‘react-infinite-scroll-component’ 라이브러리를 사용하는 방법에는 몇 가지 단계가 있습니다.

react-infinite-scroll-component 설치

먼저, npm을 사용하여 라이브러리를 설치해야 합니다.

npm install react-infinite-scroll-component --save

React 컴포넌트로 라이브러리 가져오기

설치가 완료되면, 무한 스크롤 라이브러리를 React 컴포넌트로 불러와야 합니다.

import React from 'react'
import InfiniteScroll from 'react-infinite-scroll-component'

class App extends React.Component {
constructor() {
super()
this.state = {
items: [],
hasMore: true
}
}

componentDidMount() {
this.fetchData(1)
}

fetchData = (page) => {
const newItems = []

for (let i = 0; i < 100; i++) {
newItems.push(i )
}

if (page === 100) {
this.setState({ hasMore: false })
}

this.setState({ items: [...this.state.items, ...newItems] })
}

render() {
return (
<div>
<h1>무한 스크롤</h1>
<InfiniteScroll
dataLength={this.state.items.length}
next={this.fetchData}
hasMore={this.state.hasMore}
loader={<h4>로딩 중...</h4>}
endMessage={
<p style={{ textAlign: 'center' }}>
<b>모두 다 보셨습니다!</b>
</p>
}
>
{this.state.items.map((item, index) => (
<div key={index}>
{item}
</div>
))}
</InfiniteScroll>
</div>
)
}
}

export default App

위 코드는 먼저 react-infinite-scroll-component 라이브러리에서 React와 InfiniteScroll 컴포넌트를 가져옵니다. 그런 다음, 빈 항목 배열과 ‘hasMore’ 플래그가 참으로 설정된 상태 저장 컴포넌트를 생성합니다.

매개변수 설정

‘componentDidMount’ 라이프사이클 메서드 내에서 ‘fetchData’ 메서드를 호출하며, 페이지 매개변수는 1로 설정합니다. ‘fetchData’ 메서드는 API 호출을 통해 데이터를 가져옵니다. 이 무한 스크롤 예제에서는 100개의 항목을 가진 배열을 생성하여 더미 데이터를 만듭니다.

페이지 매개변수가 100에 도달하면, 더 이상 표시할 항목이 없으므로 ‘hasMore’ 플래그를 ‘False’로 설정합니다. 이렇게 하면 InfiniteScroll 컴포넌트가 추가 API 호출을 하지 않도록 합니다. 마지막으로 새로운 데이터를 사용하여 상태를 업데이트합니다.

‘render’ 메서드는 InfiniteScroll 컴포넌트를 사용하고 여러 prop을 전달합니다. ‘dataLength’ prop은 항목 배열의 길이로 설정됩니다. ‘next’ prop은 ‘fetchData’ 메서드로 설정됩니다. ‘hasMore’ prop은 ‘hasMore’ 플래그 값과 동일하게 설정됩니다.

‘loader’ prop은 콘텐츠가 로딩 중임을 나타내는 표시기를 렌더링하도록 설정합니다. 마찬가지로, 모든 데이터 로딩이 완료되면 ‘endMessage’ prop은 메시지를 표시합니다.

InfiniteScroll 컴포넌트에 다양한 prop을 전달할 수 있지만, 위에서 언급한 prop들이 가장 자주 사용됩니다.

내장 기능 활용

React에는 무한 스크롤 구현에 활용할 수 있는 몇 가지 내장 메서드도 존재합니다.

첫 번째 방법은 ‘componentDidUpdate’를 사용하는 것입니다. React는 컴포넌트 업데이트 후 이 메서드를 호출합니다. 이 메서드를 사용하여 사용자가 페이지 하단으로 스크롤했는지 확인할 수 있습니다. 만약 그렇다면 추가 데이터를 로드합니다.

두 번째 방법은 사용자가 스크롤할 때 React가 호출하는 ‘scroll’ 이벤트를 사용하는 것입니다. 이 메서드를 사용하여 스크롤 위치를 추적할 수 있습니다. 사용자가 페이지 하단에 도달했을 때 추가 데이터를 로드할 수 있습니다.

다음은 이러한 메서드를 사용하는 방법을 보여주는 React 무한 스크롤 예제입니다.

import React, {useState, useEffect} from 'react'

function App() {
const [items, setItems] = useState([])
const [hasMore, setHasMore] = useState(true)
const [page, setPage] = useState(1)

useEffect(() => {
fetchData(page)
}, [page])

const fetchData = (page) => {
const newItems = []

for (let i = 0; i < 100; i++) {
newItems.push(i)
}

if (page === 100) {
setHasMore(false)
}

setItems([...items, ...newItems])
}

const onScroll = () => {
const scrollTop = document.documentElement.scrollTop
const scrollHeight = document.documentElement.scrollHeight
const clientHeight = document.documentElement.clientHeight

if (scrollTop + clientHeight >= scrollHeight) {
setPage(page + 1)
}
}

useEffect(() => {
window.addEventListener('scroll', onScroll)
return () => window.removeEventListener('scroll', onScroll)
}, [items])

return (
<div>
{items.map((item, index) => (
<div key={index}>
{item}
</div>
))}
</div>
)
}

export default App

이 코드는 useState 및 useEffect Hook을 활용하여 상태 및 부작용을 관리합니다.

useEffect Hook 내부에서 ‘fetchData’ 메서드를 호출하며, 현재 페이지 값을 전달합니다. ‘fetchData’ 메서드는 API 호출을 통해 데이터를 가져옵니다. 이 예제에서는 더미 데이터를 생성하여 기능을 보여줍니다.

for 루프는 100개의 정수로 ‘newItems’ 배열을 채웁니다. 페이지 매개변수가 100에 도달하면 ‘hasMore’ 플래그를 ‘False’로 설정합니다. 이렇게 하면 무한 스크롤 컴포넌트가 추가 API 호출을 하지 않도록 합니다.

마지막으로, 새로운 데이터를 사용하여 상태를 업데이트합니다.

‘onScroll’ 메서드는 스크롤 위치를 추적합니다. 사용자가 페이지 하단으로 스크롤하면 추가 데이터를 로드할 수 있습니다.

useEffect Hook은 스크롤 이벤트에 대한 이벤트 리스너를 추가합니다. 스크롤 이벤트가 발생하면 ‘onScroll’ 메서드가 호출됩니다.

React에서 무한 스크롤을 사용하는 것에는 장단점이 존재합니다. 사용자 인터페이스를 개선하여 특히 모바일 기기에서 더 원활한 경험을 제공할 수 있다는 장점이 있습니다. 하지만 사용자가 콘텐츠를 전부 확인하지 못할 수 있다는 단점도 있습니다.

웹사이트나 앱에 구현하기 전에 무한 스크롤 기술의 장단점을 충분히 검토해야 합니다.

React.js 웹사이트나 앱에 무한 스크롤을 추가하면 사용자 경험을 향상시킬 수 있습니다. 무한 스크롤 덕분에 사용자가 더 많은 콘텐츠를 보기 위해 클릭할 필요가 없어집니다. React.js 앱에서 무한 스크롤을 활용하면 페이지 로드 수를 줄여 성능을 향상시키는 효과도 얻을 수 있습니다.

또한 React 앱을 Github Pages에 무료로 쉽게 배포할 수 있다는 장점도 있습니다.