You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native FlatList多位置选中状态保持问题求助

解决React Native FlatList多选保留选中状态的问题

问题根源

你当前用useState(null)定义的selectedId只能存储单个ID,每次点击新项时会覆盖旧值,导致之前选中的项被重置。要实现多选,需要用数组或对象来存储所有选中的ID。

修改方案

核心思路

将单个ID的状态改为数组,点击项时判断当前ID是否已在数组中:存在则移除(取消选中),不存在则添加(选中)。

完整修改后的代码

import React, { useState } from 'react';
import { SafeAreaView, TouchableOpacity, Image, Text, View, FlatList } from 'react-native';

const DATA = [
  {
    id: 1,
    image: 'https://c0.wallpaperflare.com/preview/298/610/503/vietnam-ho-chi-minh-city-cityscape-dusk-thumbnail.jpg',
    title: 'Ho Chi Minh city',
  },
  {
    id: 2,
    image: 'https://c0.wallpaperflare.com/preview/582/203/631/ha-noi-city-vietnam-lake-thumbnail.jpg',
    title: 'Ha Noi city',
  },
  {
    id: 3,
    image: 'https://media.istockphoto.com/photos/sunny-beach-in-the-pearl-island-of-phu-quoc-vietnam-picture-id1307905856?b=1&k=20&m=1307905856&s=170667a&w=0&h=MMd7neh6NOOxeUUlo6eCeU49vWp7HhQXtgTw0VNjogo=',
    title: 'Phu Quoc island',
  },
  {
    id: 4,
    image: 'https://media.istockphoto.com/photos/panorama-of-the-city-of-nha-trang-in-vietnam-from-drone-point-of-view-picture-id827359312?k=20&m=827359312&s=612x612&w=0&h=4QigU_O-sGaDhuFBOS_K66A4cXxc5IUoT4NrbsPw7Oo=',
    title: 'Nha Trang city',
  },
  {
    id: 5,
    image: 'https://c0.wallpaperflare.com/preview/298/610/503/vietnam-ho-chi-minh-city-cityscape-dusk-thumbnail.jpg',
    title: 'Ho Chi Minh city',
  },
  {
    id: 6,
    image: 'https://c0.wallpaperflare.com/preview/582/203/631/ha-noi-city-vietnam-lake-thumbnail.jpg',
    title: 'Ha Noi city',
  },
  {
    id: 7,
    image: 'https://media.istockphoto.com/photos/sunny-beach-in-the-pearl-island-of-phu-quoc-vietnam-picture-id1307905856?b=1&k=20&m=1307905856&s=170667a&w=0&h=MMd7neh6NOOxeUUlo6eCeU49vWp7HhQXtgTw0VNjogo=',
    title: 'Phu Quoc island',
  },
  {
    id: 8,
    image: 'https://media.istockphoto.com/photos/panorama-of-the-city-of-nha-trang-in-vietnam-from-drone-point-of-view-picture-id827359312?k=20&m=827359312&s=612x612&w=0&h=4QigU_O-sGaDhuFBOS_K66A4cXxc5IUoT4NrbsPw7Oo=',
    title: 'Nha Trang city',
  },
];

export default function App() {
  // 用数组存储所有选中的ID,初始为空数组
  const [selectedIds, setSelectedIds] = useState([]);

  const handlePress = (itemId) => {
    setSelectedIds(prevIds => {
      // 判断当前ID是否已选中
      if (prevIds.includes(itemId)) {
        // 已选中则移除
        return prevIds.filter(id => id !== itemId);
      } else {
        // 未选中则添加
        return [...prevIds, itemId];
      }
    });
  };

  const renderView = ({item}) => (
    <TouchableOpacity 
      onPress={() => handlePress(item.id)}
      style={{
        marginBottom:15,
        marginHorizontal:7,
        width:'46%',
        height:200,
      }}
    >
      <Image 
        style={{width:'100%',height:'100%', borderRadius:20}} 
        source={{uri:item.image}}
      />
      <Text style={{position:'absolute',bottom:0,padding:15,color:'yellow', fontWeight:'bold'}}>
        {item.title}
      </Text>
      <View style={{
        position:'absolute',
        right:0,
        padding:15,
      }}>
        {
          selectedIds.includes(item.id) ? 
            <Text style={{fontWeight:'bold',color:'red'}}>Checked</Text> : 
            <Text style={{fontWeight:'bold',color:'red'}}>Not check</Text>   
        }   
      </View>
    </TouchableOpacity>
  );

  return (
    <SafeAreaView style={{flex:1}}>
      <View style={{
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
        paddingHorizontal: 15,
        paddingVertical: 10
      }}>
        <View style={{
          height:44,
          width:44,
          backgroundColor:'green',
          alignItems:'center',
          justifyContent:'center',
          borderRadius:30,
        }}>
          <Text style={{fontSize:25,color:'white'}}>=</Text>
        </View>
        <Text style={{fontSize:25,color:'blue',fontWeight:'bold'}}>Packages</Text>
        <View style={{
            height:44,
            width:44,
            backgroundColor:'green',
            alignItems:'center',
            justifyContent:'center',
            borderRadius:30,
        }}>
          <Text style={{fontSize:25,color:'white'}}>@</Text>
        </View>
      </View>

      <View style={{
          marginVertical:10,
          flex:1,
          paddingHorizontal: 15
        }}>
        <FlatList
          data={DATA}
          showsVerticalScrollIndicator={false}
          numColumns={2}
          renderItem={renderView}
          keyExtractor={(item) => item.id.toString()}
        />
      </View>
    </SafeAreaView>
  );
}

关键修改点

  • 状态从单个selectedId改为数组selectedIds,存储所有选中项的ID
  • 新增handlePress函数,实现选中/取消选中的切换逻辑
  • 渲染时通过selectedIds.includes(item.id)判断当前项的选中状态
  • 优化keyExtractor,改用item.id而非索引,避免数据更新时的渲染异常

内容的提问来源于stack exchange,提问作者Kedo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 08:00:29