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
相关产品推荐
相关产品推荐

