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

React Native数字列表多选仅显示单值 需展示全部已选数字

React Native 多选数字列表累加展示修复方案

核心问题定位

你的代码存在4处直接导致功能异常的错误:

  • 点击事件逻辑错误:onPress={() => setSelectedItems(item.NO)} 每次点击直接把存储选中项的数组覆盖为当前点击的单个数字字符串,自然只能显示最后一次点击的内容
  • 选中状态判断错误:item.NO === selectedItems 是拿单个字符串和整个数组做全等比较,永远返回false,选中高亮完全不生效
  • 展示逻辑缺失:直接渲染数组不会自动按空格拼接内容,达不到1 2 3的展示效果
  • 细节错误:漏了useNavigation的依赖引入、map循环未正确绑定key、静态数字列表多余声明了setter方法

修复后可直接运行的完整代码

import React,{useState} from "react";
import { ScrollView, SafeAreaView, View, StyleSheet, Text, TouchableOpacity } from "react-native";
// 补全原来漏引入的导航hook
import { useNavigation } from "@react-navigation/native";

const Item = ({ item, onPress, backgroundColor, textColor }) => {
  return (
    <TouchableOpacity onPress={onPress} style={[styles.item, backgroundColor]}>
      <Text style={[styles.title, textColor]}>{item.NO}</Text>
    </TouchableOpacity>
  );
}

export const FlatListComponent = () => {
  const navigation = useNavigation();
 
  // 静态列表不需要更新,去掉多余的setNumbers声明
  const [numbers] = useState([
    { id: 1, NO: '1' }, { id: 2, NO: '2' }, { id: 3, NO: '3' }, { id: 4, NO: '4' }, { id: 5, NO: '5' },
    { id: 6, NO: '6' }, { id: 7, NO: '7' }, { id: 8, NO: '8' }, { id: 9, NO: '9' }, { id: 10, NO: '10' },
    { id: 11, NO: '11' }, { id: 12, NO: '12' }, { id: 13, NO: '13' }, { id: 14, NO: '14' }, { id: 15, NO: '15' },
    { id: 16, NO: '16' }, { id: 17, NO: '17' }, { id: 18, NO: '18' }, { id: 19, NO: '19' }, { id: 20, NO: '20' },
  ]);

  const [selectedItems, setSelectedItems] = useState([]);  

  // 实现选中累加、重复点击取消选中逻辑
  const handleSelect = (no) => {
    setSelectedItems(prev => {
      if(prev.includes(no)) {
        return prev.filter(item => item !== no)
      }
      return [...prev, no]
    })
  }

  const RenderItem = ({ item }) => {
    // 正确判断当前项是否在选中列表中
    const isSelected = selectedItems.includes(item.NO);
    const backgroundColor = isSelected ? "#6e3b6e" : "#f9c2ff";
    const color = isSelected ? 'white' : 'black';

    return (
      <Item
        item={item}
        backgroundColor={{ backgroundColor }}
        textColor={{ color }}
        onPress={() => handleSelect(item.NO)}
      />
    );
  };

  return (
    <SafeAreaView style={styles.container}>
      <ScrollView contentContainerStyle={{ flexDirection: "row", flexWrap: "wrap" }}>
        {numbers.map((item) => {
          return (
            // 修正key绑定位置
            <View style={{ width: '20%', flexDirection: "row" }} key={item.id}>
              <RenderItem item={item} />
            </View>
          )
        })}
        <View style={{width: '100%', padding: 16}}>
          {/* 数组按空格拼接为字符串展示 */}
          <Text>已选中:{selectedItems.join(' ')}</Text>
        </View>
      </ScrollView>
    </SafeAreaView>
  );
};

// 补全基础样式
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  item: {
    flex: 1,
    padding: 16,
    margin: 4,
    borderRadius: 4,
    alignItems: 'center',
    justifyContent: 'center'
  },
  title: {
    fontSize: 16
  }
})

实现效果

  • 点击未选中的数字,会自动追加到已选中列表,底部展示区实时用空格拼接所有选中项
  • 点击已选中的数字,会自动从选中列表移除,展示区同步更新
  • 选中项自动切换深紫背景+白字高亮样式,未选中项为浅粉背景+黑字

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:06:22