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

Next.js向Firebase推送状态时遇错:date状态未定义

问题分析与解决方案

我需要将react-schedule-meeting组件选中的日期存入state,再推送到Firebase。但从Firebase获取时间戳格式的日期并传入日历组件时出现报错,按官方示例方式获取日期则一切正常,仅date状态返回undefined。

相关代码

日历组件代码

const [date, setDate] = useState()

<ScheduleMeeting
  primaryColor={calendarPrimary}
  eventDurationInMinutes={30}
  borderRadius={calendarRadius}
  startTimeListStyle={timeStyle}
  selectedDateMonthTitleFormatString="cccc, LLLL do"
  availableTimeslots={timestamps}
  onStartTimeSelect={setDate}
/>

推送至Firebase的代码

const handleCreate = () => {
  const db = getFirestore(app)
  if (router.query.calendar) {
    console.log('date ', date)
    setDoc(doc(db, 'links', router.query.calendar, 'meetings', meetingname), {
      timeValue: timeValue,
      name: meetingname,
      email: meetingemail,
      date: date
    }).then(notify)
  }
}

从Firebase获取数据的代码

if (docSnap.exists()) {
  setSchedule(docSnap.data())
  console.log(docSnap.data()['schedule'])
  for (var i in docSnap.data()['schedule']) {
    setTimestamps((array) => [...array, { 
      startTime: new Date(docSnap.data()['schedule'][0]['start']['seconds'] * 1000), 
      endTime: new Date(docSnap.data()['schedule'][0]['end']['seconds'] * 1000) 
    }]);
  }
} 

监听状态变化的代码(用于模态表单)

useEffect(() =>{
  if(date){
    setOpened(true)
  }
}, [date])

问题根源

  1. Firebase数据读取逻辑错误:循环中始终取schedule[0],导致timestamps数组里全是重复的同一个时间段,完全没有正确遍历所有日程数据;同时使用var会引发变量提升问题,导致循环逻辑异常。
  2. 日期状态初始化不明确:date初始值为undefined,如果日历组件因数据格式错误无法触发onStartTimeSelect事件,date会一直保持undefined状态。
  3. 组件数据格式不匹配:日历组件的availableTimeslots要求传入格式正确的时间段数组,错误的timestamps数据会导致组件内部报错,进而无法正常触发日期选择事件。

修复方案

1. 修正Firebase数据读取逻辑

把循环中的固定索引0改为当前循环变量,并替换var为let,同时用更高效的map方法生成数组:

if (docSnap.exists()) {
  const scheduleData = docSnap.data()['schedule'];
  setSchedule(scheduleData);
  // 转换为组件需要的时间段格式
  const newTimestamps = scheduleData.map(item => ({
    startTime: new Date(item.start.seconds * 1000),
    endTime: new Date(item.end.seconds * 1000)
  }));
  setTimestamps(newTimestamps);
}

2. 初始化date状态

给date设置明确的初始值,避免undefined引发的判断问题:

const [date, setDate] = useState(null)

3. 校验组件数据格式

添加数据校验,过滤无效的时间段,确保传入组件的timestamps格式完全符合要求:

if (docSnap.exists()) {
  const scheduleData = docSnap.data()['schedule'];
  setSchedule(scheduleData);
  const newTimestamps = scheduleData
    .map(item => {
      // 校验时间戳是否有效
      const hasValidTime = item.start?.seconds && item.end?.seconds;
      if (!hasValidTime) return null;
      return {
        startTime: new Date(item.start.seconds * 1000),
        endTime: new Date(item.end.seconds * 1000)
      };
    })
    .filter(Boolean); // 过滤无效项
  setTimestamps(newTimestamps);
}

4. 排查组件报错

根据报错信息(无法读取undefined的属性),确认availableTimeslots的结构与官方示例完全一致,每个时间段的startTime和endTime必须是有效的Date对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 04:30:56