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

使用map方法渲染数组时,如何让useState仅作用于单个选中项

你现在的问题核心是所有日期条目共用了同一个布尔类型的selected状态,修改这个状态自然会同步作用到所有条目上。你需要用数组类型的状态单独记录每个条目的选中情况,具体修改方式如下:

第一步:调整状态结构

把原来的布尔类型状态修改为布尔数组,长度和星期数组保持一致,初始全部为未选中:

// 若不需要TS类型标注去掉<boolean[]>即可
const [selected, setSelected] = useState<boolean[]>(new Array(dayOfWeek.length).fill(false))

另外你提供的星期数组里周二的拼写有误,"Tus"建议修正为"Tue"。

第二步:简化子组件逻辑,把选中状态的更新逻辑收敛到父组件

修改DateItem组件,不再接收setSelected,改为接收父组件传入的点击回调即可:

const DateItem = (props: DateItemProps) => {
  const { days, selected, onPress } = props

  return (
    <TouchableOpacity
      row
      center
      onPress={onPress}
      style={!selected ? CONTAINER_WITHOUT_SELECTED : CONTAINER_WITH_SELECTED}
    >
      <Text style={!selected ? TEXT_WITHOUT_SELECTED : TEXT_WITH_SELECTED}>{days}</Text>
      {selected && <Icon name="check" color="white" />}
    </TouchableOpacity>
  )
}

export default DateItem 

记得同步修改DateItemProps的类型定义,把setSelected替换为onPress: () => void。

第三步:修改列表渲染逻辑,为每个条目绑定独立的点击处理

渲染时给每个条目传入对应下标的选中状态,点击时只修改对应下标的状态值,同时补充map循环必需的key属性避免React抛出警告:

<View row style={{ flexWrap: "wrap" }}>
  {dayOfWeek.map((item, index) => (
    <View key={index}>
      <DateItem 
        days={item} 
        selected={selected[index]} 
        onPress={() => {
          // 拷贝原数组避免直接修改状态,符合React不可变数据原则
          const newSelected = [...selected]
          // 仅翻转当前点击条目的选中状态
          newSelected[index] = !newSelected[index]
          setSelected(newSelected)
        }}
      />
    </View>
  ))}
</View>

如果你的需求是单选(同一时间只能选中一个条目),可以把状态简化为存储选中条目的下标,初始值设为-1,点击时直接把状态赋值为当前点击的下标,选中判断逻辑改为selected === index即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:24:03