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

如何在React Native中用Moment.js遍历日期数组计算区间日期并标记日历

问题原因

  • 你当前仅处理了起止日期数组中的第一组数据,其余区间未参与计算
  • 存储起止日期时拆分为两个独立数组,容易出现顺序不匹配的问题
  • forEach无返回值,调用setStartDate/setEndDate时实际存入的是undefined
  • 标记日期对象如果未存入state,无法触发日历组件的重渲染
  • getDaysBetweenDates内部循环重复遍历日期数组,存在冗余逻辑

实现方案

第一步:调整数据处理逻辑,绑定同组起止日期

请求数据时直接将同一条记录的起止日期配对处理,避免拆分存储出现顺序错位。

第二步:批量计算所有区间的标记日期

遍历所有配对的起止日期,合并所有区间的日期到同一个标记对象中,存入state供日历组件使用。

修正后的完整代码如下:

// 提前声明存储标记日期的state,完全匹配React Native Calendar要求的格式
const [markedDates, setMarkedDates] = useState({});

const fetchData = async () => {
  try {
    let res = await axios.get(`https://myseenapp.herokuapp.com/constructionSite/${_id}`);
    let data = res.data;
    setConstruction(data);
    
    // 临时存储所有标记日期的对象
    const tempMarked = {};
    
    // 遍历每一条数据,直接配对当前条的起止日期,无需拆分为两个独立数组
    data.forEach(item => {
      // 转换日期格式为YYYY-MM-DD,和moment输出、日历要求格式统一
      const startStr = item.startDate.split('-').reverse().join('-');
      const endStr = item.endDate.split('-').reverse().join('-');
      const start = moment(startStr);
      const end = moment(endStr);
      
      // 计算当前区间的所有日期
      let now = start.clone(); // 复制对象避免修改原start值
      while (now.isSameOrBefore(end)) {
        const dateKey = now.format("YYYY-MM-DD");
        // 避免重复赋值覆盖已有配置
        if (!tempMarked[dateKey]) {
          tempMarked[dateKey] = {
            textColor: "white",
            color: 'gold',
            selected: true,
          }
        }
        now.add(1, 'days');
      }
    })
    
    // 把最终的标记对象存入state,触发组件重渲染
    setMarkedDates(tempMarked);
  }
  catch (err) {
    console.log(err)
  }
};

第三步:绑定到日历组件

将生成的markedDates state直接传给React Native Calendar的对应属性即可:

<Calendar
  markedDates={markedDates}
  // 保留你的其他日历配置项
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:12:02