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

react-big-calendar使用onNavigate时点击上下月后跳转回当前月问题

问题原因
  • react-big-calendar未显式传入date属性时为非受控组件,内部自行维护当前展示的日期状态
  • 你在onNavigate回调中调用setSelectedMonth更新了组件状态,触发父组件整体重渲染
  • 重渲染时Calendar未接收到外部传入的日期值,会重置为默认的当前月份,导致跳转失效
修复方案

将Calendar改为受控组件,自行维护当前展示的日期状态即可,修改后的代码如下:

import { useState, useCallback } from 'react';
import { Calendar } from 'react-big-calendar';
import moment from 'moment';
// 其余导入省略

const YourCalendarComponent = () => {
  // 新增:维护日历当前展示的日期,作为受控组件的数据源
  const [currentDate, setCurrentDate] = useState<Date>(new Date());
  const [selectedMonth, setSelectedMonth] = useState<string>(() => {
    // 初始化计算默认月份区间
    const firstDay = moment(new Date(currentDate.getFullYear(), currentDate.getMonth(), 1)).format('YYYY-MM-DD');
    const lastDay = moment(new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0)).format('YYYY-MM-DD');
    return `${firstDay}_${lastDay}`;
  });

  const getStartAndEndDate = (date: Date) => {
    const firstDay = moment(new Date(date.getFullYear(), date.getMonth(), 1)).format('YYYY-MM-DD');
    const lastDay = moment(new Date(date.getFullYear(), date.getMonth() + 1, 0)).format('YYYY-MM-DD');
    return `${firstDay}_${lastDay}`;
  };

  const onNavigate = useCallback((date: Date) => {
    const fullMonth = getStartAndEndDate(date);
    setSelectedMonth(fullMonth);
    // 同步更新当前展示的日期
    setCurrentDate(date);
  }, []);

  return (
    <Calendar
      localizer={localizer}
      events={events}
      views={['month', 'agenda']}
      onNavigate={onNavigate}
      {/* 传入受控的date属性 */}
      date={currentDate}
      startAccessor="start"
      endAccessor="end"
      style={{ height: '600px', width: '100%' }}
    />
  )
}

修改完成后,Calendar的展示日期完全由你维护的currentDate状态控制,重渲染时会沿用切换后的日期值,不会再自动跳回当前月份,同时你也可以正常获取切换后的日期计算对应的月份区间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 05:54:01