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

React Native日历应用事件展开异常:点击单个事件全部切换详情

解决React Native日历事件独立展开/收起的问题

你的问题核心在于所有事件共用了同一个全局状态,点击单个事件时触发的是全局状态变更,导致所有事件同步切换展开/收起状态。要实现单个事件独立控制,需要为每个事件维护独立的展开状态,具体修改方案如下:


1. 替换全局状态为事件级状态

把原来的isDetailed和isBlock单个布尔值,改成存储展开事件标识(索引或唯一ID)的数组,精准控制每个事件的状态:

// 替换原有的isDetailed、isBlock状态
const [expandedEventIndexes, setExpandedEventIndexes] = useState([]);

2. 修改切换函数,针对单个事件操作

更新toggleView函数,传入当前事件的索引,判断该索引是否在展开数组中,实现单个事件的状态切换:

const toggleView = (index) => {
  setExpandedEventIndexes(prevState => {
    if (prevState.includes(index)) {
      // 若已展开,移除该索引以收起
      return prevState.filter(i => i !== index);
    } else {
      // 若未展开,添加该索引以展开
      return [...prevState, index];
    }
  });
};

3. 渲染时根据当前事件状态控制显示

在事件列表的渲染逻辑中,检查当前事件的索引是否在展开数组里,以此控制详情文本的显示和图标的切换:

<Text style={styles.eventsTitle}>Events for {dateSelected}:</Text>
<ScrollView style={{ height: (calendarHeight / 1.5) + 15 }} showsVerticalScrollIndicator={false}>
  {getEventsForDay(selectedDate).map((event, index) => {
    const isExpanded = expandedEventIndexes.includes(index);
    return (
      <TouchableOpacity onPress={() => toggleView(index)} key={index}>
        <Card style={styles.eventItem}>
          <View>
            <Text style={styles.eventItemTitle}>{event.title}</Text>
            {/* 根据当前事件的展开状态控制详情显示 */}
            <Text style={{ display: isExpanded ? "flex" : "none", color: "white", marginTop: 5 }}>{event.details}</Text>
          </View>
          {/* 根据当前事件的展开状态切换图标 */}
          {isExpanded ? (
            <Ionicons
              name="chevron-up"
              color={Colors.primary}
              size={25}
            />
          ) : (
            <Ionicons
              name="chevron-down"
              color={Colors.primary}
              size={25}
            />
          )}
        </Card>
      </TouchableOpacity>
    );
  })}
</ScrollView>

可选优化:用事件唯一ID代替索引

如果你的事件列表可能出现顺序变化(比如新增/删除事件),建议给每个事件添加唯一id字段,用ID代替索引来维护状态,避免索引错位:

// 给events数组添加唯一id
const events = [
  { id: 1, title: 'Maths Exam', date: '2023-04-17', time_start: "HH:MM", time_end: "HH:MM", duration: "HH:MM", teacher: "Ms. Sonila", details: "Lorem Ipsum Dolor Sit amet" },
  { id: 2, title: 'English Quiz', date: '2023-04-17', time_start: "HH:MM", time_end: "HH:MM", duration: "HH:MM", teacher: "Ms. Morena", details: "Lorem Ipsum Dolor Sit amet" },
  // 其余事件同理
];

// 状态和切换函数改为基于ID
const [expandedEventIds, setExpandedEventIds] = useState([]);
const toggleView = (eventId) => {
  setExpandedEventIds(prevState => {
    if (prevState.includes(eventId)) {
      return prevState.filter(id => id !== eventId);
    } else {
      return [...prevState, eventId];
    }
  });
};

// 渲染时判断逻辑
const isExpanded = expandedEventIds.includes(event.id);
// onPress={() => toggleView(event.id)}

效果展示

点击前状态:
Before detailed view

点击单个事件后的状态(仅该事件展开):
After detailed view with single event expanded

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:20:14