如何在 React Native 中创建流畅的无限 Tinder 风格滑动卡片堆
Source: Dev.to
概览
Tinder 风格的滑动卡片 UI 是移动应用中标志性且直观的交互模式。无论你是在构建习惯跟踪器、待办事项列表,还是社交应用,为用户提供“滑动”浏览项目的能力都极具吸引力。
在本指南中,我们将展示如何在 React Native 中使用以下技术创建无限、流畅的滑动卡组:
rn‑swiper‑list– 滑动卡组的核心库- React Query – 用于获取数据(例如习惯列表)
- Zustand – 简单的状态管理
创建无限卡组
当用户滑动到最后一张卡片时,我们希望第一张卡片重新出现。关键在于永不从数据数组中移除已滑动的卡片,而是将第一项移动到数组末尾。
// Example state (Zustand or useState)
const [habits, setHabits] = useState(initialHabits);
const moveToEnd = () => {
setHabits(prev => {
const [first, ...rest] = prev;
return [...rest, first];
});
};
通过向 <Swiper> 组件传递依赖于数据的 key 属性(例如 key={habits.map(h => h.id).join('-')}),状态更新会强制 React 重新渲染卡组,从而实现卡片循环。
防止卡顿和不流畅的动画
卡顿产生的原因
rn‑swiper‑list 默认的滑动动画时长约为 500 ms。如果在滑动发生时立即更新状态,组件会在动画完成前重新渲染,导致明显的卡顿。
setTimeout 小技巧
将状态更新延迟到动画结束后再执行:
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 的延迟与默认动画时长相匹配,使卡片能够完整滑出屏幕后才重新排列数据数组。随后下一张卡片平滑滑入,实现无缝的无限循环。
在卡片内部添加自定义滑动按钮
如果你更倾向于在卡片内部放置“喜欢”或“拒绝”按钮,而不是使用外部控件,可以通过 ref 编程式触发滑动。
步骤详解
-
在父组件中创建 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 的复杂自定义交互。
小结
- 保持数据数组完整,通过旋转项来实现无限循环。
- 使用
setTimeout延迟状态更新(与动画时长保持一致),以避免卡顿。 - 利用 ref 在卡片内部触发滑动,实现自定义按钮控制。
掌握这些技巧后,你就可以在 React Native 中构建高性能、无限的 Tinder 风格滑动卡组。