如何用react-native-gesture-handler实现点击/滑动其他项时收回已滑开列表项
React Native Gesture Handler 实现滑动列表项互斥关闭(仅保持一项展开)
我尝试用react-native-gesture-handler的Swipeable组件实现列表项的互斥滑动——当滑动或点击其他列表项时,自动收回已滑开的项。参考过相关示例和Issue但未成功,当前代码中prevOpenedRow始终输出undefined,无法实现预期效果。
原代码问题分析
- 父组件中用普通变量
prevOpenedRow和row存储状态,React组件重新渲染时这些变量会被重置,无法持久保存状态 - 子组件修改
prevOpenedRow只是操作自身接收的props副本,无法同步到父组件的变量,导致状态无法共享
解决方案
使用React的useRef持久保存所有列表项的Swipeable引用,用useState跟踪当前展开的项索引,通过父组件统一管理展开状态,实现互斥关闭。
修改后代码
List.js
import { useState, useRef } from 'react'; import { FlatList } from 'react-native'; import Child from './Child'; const List = () => { // 用useRef持久存储所有Swipeable组件的引用 const rowRefs = useRef([]); // 用useState跟踪当前展开的项索引 const [openRowIndex, setOpenRowIndex] = useState(null); // 处理行展开的方法:关闭之前的行,更新当前展开索引 const handleRowOpen = (index) => { // 如果之前有展开的行,且不是当前行,关闭它 if (openRowIndex !== null && openRowIndex !== index) { rowRefs.current[openRowIndex]?.close(); } // 更新当前展开的索引(点击已展开行则收起) setOpenRowIndex(index === openRowIndex ? null : index); }; return ( <FlatList data={dataArray} keyExtractor={(item) => item.id} renderItem={({ item, index }) => ( <Child item={item} index={index} onRowOpen={handleRowOpen} setRowRef={(ref) => (rowRefs.current[index] = ref)} /> )} /> ); }; export default List;
Child.js
import { View } from 'react-native'; import { Swipeable } from 'react-native-gesture-handler'; const Child = ({ item, index, onRowOpen, setRowRef }) => { // 自定义右侧滑动操作组件,根据需求替换 const swipeRightComps = () => { return ( <View style={{ width: 100, backgroundColor: '#ff4444', justifyContent: 'center', alignItems: 'center' }}> {/* 这里是你的右侧操作按钮,比如删除、编辑等 */} </View> ); }; return ( <Swipeable renderRightActions={swipeRightComps} ref={(ref) => setRowRef(ref)} onSwipeableOpen={() => onRowOpen(index)} // 可选:点击行内容时也触发关闭其他行 onPress={() => onRowOpen(index)} > {/* 列表项内容 */} <View style={{ padding: 16, borderBottomWidth: 1, borderBottomColor: '#eee' }}> {/* 显示item内容 */} </View> </Swipeable> ); }; export default Child;
关键说明
rowRefs.current存储所有Swipeable的引用,useRef确保组件重新渲染时引用不会丢失openRowIndex跟踪当前展开的项索引,通过useState触发组件更新,保证状态同步- 父组件统一处理展开逻辑,子组件只负责调用父方法并传递自身引用,避免状态分散
内容的提问来源于stack exchange,提问作者JeremyFc
相关产品推荐
相关产品推荐

