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

React中使用createRef获取FullCalendar实例时出现Cannot read properties of null (reading 'getApi')错误,如何获取下周视图的开始日期?

解决FullCalendar Cannot read properties of null (reading 'getApi') 错误并获取视图开始日期

问题原因

你在render()函数里调用getDateResult(),但此时FullCalendar组件还没有完成挂载——React的render阶段只是生成虚拟DOM,还没把真实DOM渲染到页面上,所以calendarRef.current还是null,自然调用getApi()会报错。而且render函数是用来描述UI的,不应该在这里执行获取组件实例这类副作用操作。

解决方案:利用FullCalendar的官方回调或生命周期钩子

方案1:使用datesSet回调(推荐,完美匹配你的需求)

FullCalendar提供了datesSet回调,每当日历的视图日期范围发生变化(比如切换到下周、切换视图类型)时,会自动触发这个回调,并且传入包含当前视图起止日期的info对象。你可以直接通过这个回调获取视图的开始日期,甚至不需要手动操作ref:

export default class DemoApp extends React.Component { 
  today = new Date(); 
  calendarRef = createRef(); 

  // 新增处理日期变化的回调
  handleDatesSet = (info) => {
    // 当前视图的开始日期
    const currentViewStart = info.start;
    console.log('当前视图开始日期:', currentViewStart);

    // 如果需要获取下周视图的开始日期,直接计算即可
    const nextWeekStart = new Date(currentViewStart);
    nextWeekStart.setDate(nextWeekStart.getDate() + 7);
    console.log('下周视图开始日期:', nextWeekStart);
  }

  render() { 
    const workMin = this.state.hours.map(item => item.startTime).sort().shift(); 
    const workMax = this.state.hours.map(item => item.endTime).sort().pop(); 

    return ( 
      <div className='demo-app'> 
        {this.renderSidebar()} 
        <div className='demo-app-main'> 
          <FullCalendar 
            ref={this.calendarRef} 
            plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]} 
            headerToolbar={{ left: 'prev,next today', center: 'title' }} 
            locale="hr" 
            initialView='timeGridWeek' 
            editable={true} 
            selectable={true} 
            selectMirror={true} 
            dayMaxEvents={true} 
            weekends={this.state.weekendsVisible} 
            initialEvents={INITIAL_EVENTS} 
            select={this.handleDateSelect} 
            eventContent={renderEventContent} 
            eventClick={this.handleEventClick} 
            eventsSet={this.handleEvents} 
            eventStartEditable={false} 
            slotMinTime={workMin} 
            slotMaxTime={workMax} 
            validRange={{ start: this.today }} 
            events={this.state.morningBgEvent} 
            datesSet={this.handleDatesSet} {/* 新增这个回调 */}
          /> 
        </div> 
      </div> 
    ) 
  } 
}

方案2:在生命周期钩子中获取API实例

如果只是在组件挂载后获取一次当前视图的开始日期,可以用componentDidMount钩子(类组件的挂载后生命周期),此时FullCalendar已经完成挂载,ref会正确指向组件实例:

componentDidMount() {
  // 此时calendarRef.current已经有值了
  const calendarApi = this.calendarRef.current.getApi();
  console.log('当前视图开始日期:', calendarApi.activeStart);

  // 计算下周开始日期
  const nextWeekStart = new Date(calendarApi.activeStart);
  nextWeekStart.setDate(nextWeekStart.getDate() + 7);
  console.log('下周视图开始日期:', nextWeekStart);
}

注意事项

  • 永远不要在render函数里执行副作用(比如获取组件实例、发起请求等),render应该是纯函数,只根据props和state返回UI。
  • FullCalendar的官方回调(比如datesSet、eventClick等)是和日历交互的最佳方式,比手动操作ref更可靠,能避免组件生命周期的时序问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 17:08:12