如何通过ListItem的onPress切换FlatList列表项的selected状态
解决FlatList列表项点击切换selected状态的问题
你遇到的核心问题是没有把点击项的标识传递给_onPressItem函数,所以只能拿到事件对象,找不到对应的数据项。这里给你两种简单直接的解决思路:
方法一:传递点击项的key给_onPressItem
首先修改你的_renderItem,在onPress里用箭头函数包裹,把当前item的key传进去:
_renderItem = ({item, index}) => ( <ListItem title={item.title} avatar={getFlag(item.key)} onPress={() => this._onPressItem(item.key)} // 传递当前项的key rightIcon={{name: 'done'}} hideChevron={!item.selected} /> )
然后编写_onPressItem函数,通过key找到对应项并切换selected状态(注意要保持state的不可变性,不能直接修改原数组):
_onPressItem = (targetKey) => { this.setState(prevState => { // 复制原数据数组,遍历找到对应项修改selected const updatedData = prevState.data.map(item => { if (item.key === targetKey) { // 展开原item,只修改selected属性 return {...item, selected: !item.selected}; } // 其他项保持不变 return item; }); return {data: updatedData}; }); };
方法二:传递点击项的索引index
如果觉得用key不够直接,也可以传递index:
修改_renderItem的onPress:
onPress={() => this._onPressItem(index)}
对应的_onPressItem:
_onPressItem = (targetIndex) => { this.setState(prevState => { // 先复制原数组,避免直接修改state const updatedData = [...prevState.data]; // 找到对应索引的项,切换selected updatedData[targetIndex] = { ...updatedData[targetIndex], selected: !updatedData[targetIndex].selected }; return {data: updatedData}; }); };
为什么官方示例用Map?
你提到的FlatList官方示例里用了Map来存储selected状态,那是因为示例把选中状态单独抽离成了一个Map(key是项的id,value是选中状态),而你的数据结构是把selected直接放在每个item对象里,所以不需要用Map,直接修改data数组里的对应项即可。
完整代码示例
把修改后的代码整合起来,大概是这样:
class YourComponent extends React.Component { state = { data: [ {key: 'DE', title: 'DE', selected: true}, {key: 'FR', title: 'FR', selected: true}, {key: 'GB', title: 'GB', selected: false}, {key: 'US', title: 'US', selected: false}, {key: 'GE', title: 'GE', selected: true}, {key: 'JP', title: 'JP', selected: true}, ], }; _keyExtractor = (item) => item.key; _onPressItem = (targetKey) => { this.setState(prevState => { const updatedData = prevState.data.map(item => { if (item.key === targetKey) { return {...item, selected: !item.selected}; } return item; }); return {data: updatedData}; }); }; _renderItem = ({item, index}) => ( <ListItem title={item.title} avatar={getFlag(item.key)} onPress={() => this._onPressItem(item.key)} rightIcon={{name: 'done'}} hideChevron={!item.selected} /> ); render() { return ( <List containerStyle={{marginTop: 0}}> <FlatList data={this.state.data} keyExtractor={this._keyExtractor} renderItem={this._renderItem} /> </List> ); } }
这样点击每个ListItem的时候,就能正确切换对应项的selected状态,勾选图标也会跟着显示/隐藏了。
内容的提问来源于stack exchange,提问作者Liren Yeo
相关产品推荐
相关产品推荐

