dev/React Native

React Native에서 react-native-reanimated-carousel로 커스텀 페이지네이션 구현하기

wndud587 2024. 11. 26. 14:30
728x90

오늘은 React Native를 활용해 react-native-reanimated-carousel 라이브러리로 캐러셀을 구현하고, 이를 커스텀 페이지네이션으로 개선하는 방법을 소개합니다.

캐러셀은 여러 화면을 스크롤로 전환할 수 있는 인기 있는 UI 요소로, 제품 갤러리, 문제 풀이 앱 등에서 자주 사용됩니다. 이번 글에서는 캐러셀 구성 과정과 커스텀 페이지네이션 추가 방법을 단계별로 살펴보겠습니다.

 

1. 캐러셀 사용 시 발생할 수 있는 에러

공식 문서를 참고해 react-native-reanimated-carousel을 구현하다 보면 아래와 같은 에러가 발생할 수 있습니다.

Warning: TypeError: Cannot read property 'Basic' of undefined  

This error is located at:  
    in SensesScreen (created by SceneView)  
    in StaticContainer  
    in EnsureSingleNavigator (created by SceneView)  
    in SceneView (created by NativeStackNavigator)  
    in RNSScreenContentWrapper (created by ScreenContentWrapper)

 

위 에러는 라이브러리 버전 간 호환성 문제나 누락된 속성으로 인해 발생할 가능성이 큽니다. 이런 문제를 방지하기 위해 기본적인 캐러셀 기능 구현에 집중하며 커스터마이징을 진행하겠습니다.

 

2. 커스텀 페이지네이션 추가하기

2-1. 전체 코드

다음은 캐러셀과 커스텀 페이지네이션을 구현한 코드입니다.

 

import React, { useRef, useState } from 'react';
import { Dimensions, Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Carousel from 'react-native-reanimated-carousel';

const { width } = Dimensions.get('window');

const CustomPagination = ({ data, currentIndex, onPress }) => (
  <View style={styles.paginationContainer}>
    {data.map((_, index) => (
      <TouchableOpacity
        key={index}
        style={[styles.dot, currentIndex === index && styles.activeDot]}
        onPress={() => onPress(index)}
      />
    ))}
  </View>
);

const App = () => {
  const data = [
    { id: 1, title: 'Page 1' },
    { id: 2, title: 'Page 2' },
    { id: 3, title: 'Page 3' },
  ];
  const [currentIndex, setCurrentIndex] = useState(0);
  const ref = useRef(null);

  const handlePaginationPress = index => {
    setCurrentIndex(index);
    ref.current?.scrollTo({ index, animated: true });
  };

  return (
    <View style={styles.container}>
      <Carousel
        ref={ref}
        width={width}
        data={data}
        onSnapToItem={index => setCurrentIndex(index)}
        renderItem={({ item }) => (
          <View style={styles.carouselItem}>
            <Text>{item.title}</Text>
          </View>
        )}
      />
      <CustomPagination
        data={data}
        currentIndex={currentIndex}
        onPress={handlePaginationPress}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  carouselItem: {
    justifyContent: 'center',
    alignItems: 'center',
    height: 200,
  },
  paginationContainer: {
    flexDirection: 'row',
    justifyContent: 'center',
    marginTop: 10,
  },
  dot: {
    width: 10,
    height: 10,
    borderRadius: 5,
    backgroundColor: '#ccc',
    marginHorizontal: 5,
  },
  activeDot: {
    backgroundColor: '#000',
  },
});

export default App;

 

2-2. 구성 요소 설명

  1. CustomPagination 컴포넌트
    • 역할: 도트 형태의 페이지네이션 UI를 렌더링합니다.
    • 주요 기능:
      • currentIndex를 기준으로 현재 활성화된 도트의 스타일을 변경합니다.
      • 도트를 누르면 onPress를 호출해 해당 페이지로 이동합니다.
  2. Carousel 컴포넌트
    • 역할: 데이터를 기반으로 캐러셀 슬라이드를 생성합니다.
    • 주요 기능:
      • onSnapToItem으로 슬라이드 이동 시 currentIndex를 업데이트합니다.
      • data 배열의 각 항목을 렌더링합니다.

2-3. 작동 흐름

데이터 설정
캐러셀에서 사용할 데이터를 배열로 정의합니다.

const data = [
  { id: 1, title: 'Page 1' },
  { id: 2, title: 'Page 2' },
  { id: 3, title: 'Page 3' },
];

 

캐러셀 동작

  • Carousel 컴포넌트가 데이터를 기반으로 슬라이드를 생성합니다.
  • 사용자가 슬라이드를 스와이프하면 onSnapToItem 이벤트가 호출되어 currentIndex를 업데이트합니다.

페이지네이션 동작

  • CustomPagination 컴포넌트는 currentIndex를 기준으로 도트 스타일을 업데이트합니다.
  • 사용자가 도트를 누르면 handlePaginationPress가 호출되고, scrollTo 메서드로 해당 페이지로 이동합니다.

 

3. 결과 화면

위 코드를 실행하면 캐러셀과 커스텀 페이지네이션이 연동된 UI가 나타납니다. 사용자는 도트를 클릭하거나 슬라이드를 스와이프해 원하는 페이지로 이동할 수 있습니다.

 

React Native 커스텀 페이지네이션

 

 

 

 

 

* 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

728x90