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

如何通过Ref API实现FullCalendar自定义日期范围?

如何通过Ref API为FullCalendar实现自定义日期范围

完全可以通过FullCalendar的Ref API实现自定义日期范围控制,不用依赖visibleRange props(这正是你遇到无限循环的原因)。直接调用Calendar实例的setVisibleRange方法就能修改视图的日期范围,具体实现步骤如下:

1. 为日期输入框添加状态与触发逻辑

在CustomCalendarHeader组件中,添加状态存储起止日期,并实现范围应用函数:

const CustomCalendarHeader: React.FC<Props> = ({
  calendarRef,
  currentDate,
  setCurrentDate,
}) => {
  const ref = calendarRef.current!.getApi();
  // 新增日期状态
  const [startDate, setStartDate] = useState<string>('');
  const [endDate, setEndDate] = useState<string>('');

  // 原有按钮逻辑保持不变
  const nextHandle = () => {
    ref.next();
  };
  const prevHandle = () => {
    ref.prev();
  };
  const todayHandle = () => {
    ref.today();
  };
  const dayHandle = () => {
    ref.changeView('resourceTimelineDay');
  };
  const weekHandle = () => {
    ref.changeView('resourceTimelineWeek');
  };

  // 自定义日期范围应用函数
  const applyCustomRange = () => {
    if (startDate && endDate) {
      // FullCalendar的end日期是排他性的,需将结束日期+1天以包含目标日期
      const adjustedEndDate = new Date(endDate);
      adjustedEndDate.setDate(adjustedEndDate.getDate() + 1);
      // 调用API设置可见范围
      ref.setVisibleRange({
        start: startDate,
        end: adjustedEndDate.toISOString().split('T')[0]
      });
    }
  };

  return (
    <Box
      sx={{
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'space-between',
        px: 2,
        mb: 5,
      }}
    >
      <Box
        sx={{ display: 'flex', alignItems: 'center', gap: 2, flexGrow: 0.3 }}
      >
        <Button variant="contained" onClick={dayHandle}>
          Day
        </Button>
        <Button variant="contained" onClick={weekHandle}>
          Week
        </Button>

        <Typography>Custom: </Typography>
        <TextField 
          type="date" 
          size="small" 
          sx={{ maxWidth: '125px' }}
          value={startDate}
          onChange={(e) => setStartDate(e.target.value)}
        />
        -
        <TextField 
          type="date" 
          size="small" 
          sx={{ maxWidth: '125px' }}
          value={endDate}
          onChange={(e) => setEndDate(e.target.value)}
        />
        {/* 添加应用按钮触发范围设置 */}
        <Button variant="outlined" onClick={applyCustomRange}>
          Apply
        </Button>
      </Box>
      <ButtonGroup
        color="primary"
        variant="contained"
        sx={{ display: 'flex', alignItems: 'center' }}
      >
        <Button onClick={prevHandle}>Prev</Button>
        <Button onClick={todayHandle}>Today</Button>
        <Button onClick={nextHandle}>Next</Button>
      </ButtonGroup>
    </Box>
  );
};

2. 移除日历组件中的visibleRange配置

由于已经通过Ref API直接控制视图范围,无需再绑定visibleRange props,彻底避免datesSet与setCurrentDate触发的无限循环:

<FullCalendar
  eventDrop={handleResizeOrRedropEvent}
  eventResize={handleResizeOrRedropEvent}
  droppable={true}
  eventReceive={handleEventReceive}
  viewDidMount={handleViewChange}
  ref={refCalendar as LegacyRef<FullCalendar> | undefined}
  nowIndicator
  dayMaxEvents
  timeZone="UTC"
  height="80vh"
  datesSet={(arg) => setCurrentDate(arg)}
  displayEventTime={false}
  eventClick={handleEventClick}
  eventsSet={handleEvents}
  weekends={true}
  editable={true}
  selectable={true}
  plugins={[resourceTimelinePlugin, interactionPlugin]}
  events={[dragEventRow, ...timeFrames]}
  resources={[dragEventRow, ...timeFrames].map((timeframe) => ({
    id: `${timeframe.type}-${timeframe.title}`,
    title: timeframe.title,
    type: timeframe.type,
    ...('children' in timeframe && {
      children: timeframe.children,
    }),
  }))}
  resourceGroupField="type"
  resourceAreaWidth={'20%'}
  initialView="resourceTimeline"
  eventContent={renderEventContent}
  headerToolbar={{
    left: '',
    center: 'title',
    right: '',
  }}
/>

核心说明

  • setVisibleRange是FullCalendar原生API方法,通过Ref调用不会触发组件重渲染循环
  • 注意FullCalendar的end日期为排他性设置,若需包含目标结束日期,需将日期+1天
  • 若需要自动应用范围,可将applyCustomRange绑定到日期输入框的onChange事件(例如当两个日期都有值时自动触发)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 09:47:49