React Native에서 부드럽고 무한한 Tinder 스타일 스와이프 덱 만들기

발행: (2025년 12월 12일 오후 10:44 GMT+9)
5 min read
원문: Dev.to

Source: Dev.to

Overview

Tinder‑style 스와이프 카드 UI는 모바일 앱에서 아이콘이자 직관적인 패턴입니다. 습관 트래커, 할 일 목록, 소셜 앱 등 어떤 앱을 만들든 사용자가 아이템을 “스와이프”할 수 있게 하면 매우 몰입감 있게 만들 수 있습니다.

이 가이드에서는 다음을 사용해 무한하고 부드러운 스와이프 덱을 React Native에서 만드는 방법을 보여드립니다:

  • rn‑swiper‑list – 스와이프 덱을 위한 핵심 라이브러리
  • React Query – 데이터 가져오기(예: 습관 목록)용
  • Zustand – 간단한 상태 관리

Creating an Infinite Deck

사용자가 마지막 카드를 스와이프했을 때 첫 번째 카드가 다시 나타나야 합니다. 핵심은 스와이프된 카드를 데이터 배열에서 절대 제거하지 않는 것입니다. 대신 첫 번째 항목을 배열 끝으로 옮깁니다.

// Example state (Zustand or useState)
const [habits, setHabits] = useState(initialHabits);

const moveToEnd = () => {
  setHabits(prev => {
    const [first, ...rest] = prev;
    return [...rest, first];
  });
};

데이터에 의존하는 key prop<Swiper> 컴포넌트에 전달하면(key={habits.map(h => h.id).join('-')} 등) 상태 업데이트가 React에게 덱을 다시 렌더링하도록 강제하고, 카드가 순환하게 됩니다.

Preventing Lag and Janky Animations

Why Lag Happens

rn‑swiper‑list는 기본 스와이프 애니메이션 시간이 500 ms 정도입니다. 스와이프가 발생했을 때 상태를 즉시 업데이트하면 애니메이션이 끝나기 전에 컴포넌트가 다시 렌더링되어 눈에 띄는 지연이 발생합니다.

The setTimeout Trick

애니메이션이 끝날 때까지 상태 업데이트를 지연시킵니다:

const onSwipe = () => {
  // Do NOT update state here – it causes lag
  // moveToEnd(); // ❌

  // Update after the animation duration (500 ms)
  setTimeout(() => {
    moveToEnd(); // ✅
  }, 500);
};

return (
  <Swiper
    onSwipedLeft={onSwipe}
    onSwipedRight={onSwipe}
    // other props…
  />
);

500 ms 지연은 기본 애니메이션 시간과 일치하므로 카드가 화면 밖으로 완전히 사라진 뒤에 데이터 배열이 재정렬됩니다. 그 다음 카드가 부드럽게 슬라이드 인되어 끊김 없는 무한 루프를 구현할 수 있습니다.

Adding Custom Swipe Buttons Inside Cards

외부 컨트롤 대신 카드 내부에 “like” 혹은 “nope” 버튼을 두고 싶다면 ref를 이용해 프로그래밍적으로 스와이프를 트리거할 수 있습니다.

Step‑by‑Step

  1. 부모 컴포넌트에서 ref 생성:

    const swiperRef = useRef(null);
  2. ref를 <Swiper>에 전달:

    <Swiper ref={swiperRef} /* other props */ />
  3. 필요하다면 각 카드 컴포넌트에 ref 전달.

  4. HabitCard 내부에서 ref 사용하여 내장 스와이프 메서드 호출:

    // Inside HabitCard.tsx
    import { Pressable, Text } from 'react-native';
    
    const HabitCard = ({ card, swiperRef }) => (
      <>
        {/* Render card content */}
        <Pressable onPress={() => swiperRef.current?.swipeLeft()}>
          <Text>Nope</Text>
        </Pressable>
    
        <Pressable onPress={() => swiperRef.current?.swipeRight()}>
          <Text>Like</Text>
        </Pressable>
      </>
    );

이 버튼들을 통해 스와이프 덱을 완전히 제어할 수 있으며, Tinder나 Bumble과 같은 복잡하고 커스텀한 UI 인터랙션을 구현할 수 있습니다.

Summary

  1. 데이터 배열을 그대로 유지하고 항목을 순환시켜 무한 루프를 구현합니다.
  2. setTimeout으로 상태 업데이트를 지연시켜(애니메이션 시간과 동일) 지연 현상을 방지합니다.
  3. ref를 사용해 카드 컴포넌트 내부에서 스와이프를 트리거함으로써 커스텀 버튼 컨트롤을 제공합니다.

이러한 기법들을 활용하면 React Native에서 성능이 뛰어나고 무한히 돌아가는 Tinder‑style 스와이프 덱을 손쉽게 만들 수 있습니다.

Back to Blog

관련 글

더 보기 »