React Native에서 부드럽고 무한한 Tinder 스타일 스와이프 덱 만들기
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
-
부모 컴포넌트에서 ref 생성:
const swiperRef = useRef(null); -
ref를
<Swiper>에 전달:<Swiper ref={swiperRef} /* other props */ /> -
필요하다면 각 카드 컴포넌트에 ref 전달.
-
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
- 데이터 배열을 그대로 유지하고 항목을 순환시켜 무한 루프를 구현합니다.
setTimeout으로 상태 업데이트를 지연시켜(애니메이션 시간과 동일) 지연 현상을 방지합니다.- ref를 사용해 카드 컴포넌트 내부에서 스와이프를 트리거함으로써 커스텀 버튼 컨트롤을 제공합니다.
이러한 기법들을 활용하면 React Native에서 성능이 뛰어나고 무한히 돌아가는 Tinder‑style 스와이프 덱을 손쉽게 만들 수 있습니다.