
모바일 앱을 개발할 때 사용자 경험을 향상시키는 중요한 기능 중 하나는 무한 스크롤(Infinite Scroll)입니다.
사용자가 콘텐츠의 끝까지 스크롤할 때 자동으로 새로운 데이터를 로드하는 이 기능은 페이지 번호를 클릭하거나 '더 보기' 버튼을 누르는 번거로움을 줄여줍니다.
이 글에서는 React Native에서 무한 스크롤을 구현하는 방법에 대해 살펴보겠습니다.
무한 스크롤은 다음과 같은 장점을 제공합니다:
React Native에서 무한 스크롤을 구현하는 방법은 여러 가지가 있지만, 여기서는 ScrollView를 사용한 기본적인 방법을 알아보겠습니다.
먼저 필요한 상태 변수들을 설정합니다:
const [allData, setAllData] = useState([]);
const [currentPage, setCurrentPage] = useState(0);
const [totalPages, setTotalPages] = useState(0);
const [loading, setLoading] = useState(true);
const [isLoadingMore, setIsLoadingMore] = useState(false);
데이터를 가져오는 함수를 만듭니다:
const fetchData = async (page = 0, isLoadingMore = false) => {
try {
setLoading(!isLoadingMore);
const response = await api.get("/data", {
params: {
page,
size: 10,
},
});
if (response.data?.items && Array.isArray(response.data.items)) {
const newData = isLoadingMore
? [...allData, ...response.data.items]
: response.data.items;
setAllData(newData);
setTotalPages(response.data.totalPages);
setCurrentPage(page);
}
} catch (error) {
console.error("Error fetching data:", error);
} finally {
setLoading(false);
setIsLoadingMore(false);
}
};
사용자가 화면 하단에 가까워졌을 때 더 많은 데이터를 로드하는 함수를 만듭니다:
const loadMoreData = async () => {
if (isLoadingMore || currentPage >= totalPages - 1) return;
setIsLoadingMore(true);
await fetchData(currentPage + 1, true);
};
ScrollView 컴포넌트에 onScroll 이벤트 핸들러를 추가합니다:
<ScrollView
style={styles.container}
onScroll={({ nativeEvent }) => {
const { layoutMeasurement, contentOffset, contentSize } = nativeEvent;
const isCloseToBottom = layoutMeasurement.height + contentOffset.y >= contentSize.height - 20;
if (isCloseToBottom && !loading && !isLoadingMore) {
loadMoreData();
}
}}
scrollEventThrottle={400}
>
{/* 데이터 렌더링 */}
{allData.map((item) => (
<View key={item.id}>{renderItem({ item })}</View>
))}
{/* 로딩 표시 */}
{isLoadingMore && (
<View style={styles.loadingMoreContainer}>
<Text style={styles.loadingText}>더 불러오는 중...</Text>
</View>
)}
</ScrollView>
여기서 주목할 부분은 다음과 같습니다:
isCloseToBottom 변수는 사용자가 화면 하단에 20픽셀 이내로 가까워졌는지 확인합니다.scrollEventThrottle={400}은 스크롤 이벤트가 발생하는 빈도를 400ms로 제한하여 성능을 최적화합니다.컴포넌트가 마운트될 때 초기 데이터를 로드합니다:
useEffect(() => {
fetchData(0);
}, []);
무한 스크롤을 구현할 때 고려해야 할 몇 가지 최적화 방법이 있습니다:
useMemo와 useCallback을 사용하여 불필요한 재렌더링을 방지합니다.FlatList나 RecyclerListView와 같은 가상화된 리스트 컴포넌트를 고려하세요.더 많은 성능 최적화가 필요하다면 ScrollView 대신 FlatList를 사용할 수 있습니다. FlatList는 화면에 보이는 항목만 렌더링하여 메모리 사용을 최적화합니다:
<FlatList
data={allData}
renderItem={renderItem}
keyExtractor={(item) => item.id.toString()}
onEndReached={loadMoreData}
onEndReachedThreshold={0.1}
ListFooterComponent={isLoadingMore ? <LoadingIndicator /> : null}
/>
FlatList는 onEndReached 속성을 통해 무한 스크롤을 더 쉽게 구현할 수 있게 해줍니다.
무한 스크롤은 모바일 앱에서 사용자 경험을 향상시키는 강력한 패턴입니다.
React Native에서는 ScrollView의 onScroll 이벤트나 FlatList의 onEndReached 이벤트를 활용하여 쉽게 구현할 수 있습니다. 데이터 캐싱, 지연 로딩, 가상화 등의 최적화 기법을 함께 사용하면 더욱 효율적인 무한 스크롤을 구현할 수 있습니다.
사용자가 끊김 없이 콘텐츠를 소비할 수 있도록 무한 스크롤을 구현하고, 앱의 성능과 사용자 경험을 향상시켜 보세요!