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

React AntDesign Calendar切换月份时重复选中日期问题

问题解决:Antd Calendar切换月份时重复触发选中状态更新

问题描述

实现点击日期将选中日期存入状态,但切换月份时,之前选中的日期会被重复存入状态,onSelect事件会触发两次并返回两个Dayjs对象,导致控制台日志重复,状态出现异常。

原因分析

Antd Calendar组件在切换月份时,内部状态更新可能会意外触发onSelect回调,而非仅在用户主动点击日期时触发,这导致状态更新逻辑被重复执行。

解决方案

在onSelect回调中通过事件对象判断触发来源,仅处理用户主动点击的情况,避免组件内部更新导致的意外触发。

修改后的代码

import React from 'react';
import { Calendar } from 'antd';
import dayjs, { Dayjs } from 'dayjs';

export default function App() {
  const [selectedDays, setSelectedDays] = React.useState<Dayjs[]>([]);

  console.log(selectedDays);

  const dateCellRender = (value: Dayjs) => {
    // 为选中日期设置不同样式
    if (selectedDays.some(day => day.isSame(value, 'day'))) {
      return (
        <div className="h-28 m-1 rounded hover:bg-blue-100 bg-blue-200 transition-all">
          {value.date()}
        </div>
      );
    } else {
      return (
        <div className="h-28 rounded border-t hover:bg-blue-100 transition-all">
          {value.date()}
        </div>
      );
    }
  };

  return (
    <div className="m-10">
      <Calendar
        onSelect={(value, event) => {
          // 仅响应用户主动点击的选择操作
          if (!event || event.type !== 'click') return;

          setSelectedDays(prev => {
            const isSelected = prev.some(day => day.isSame(value, 'day'));
            if (isSelected) {
              // 已选中则移除
              return prev.filter(day => !day.isSame(value, 'day'));
            } else {
              // 未选中则添加
              return [...prev, value];
            }
          });
        }}
        fullCellRender={dateCellRender}
      />
    </div>
  );
}

说明

  • 通过判断event.type === 'click',确保只有用户点击日期时才执行状态更新,过滤掉组件内部切换月份时的意外触发。
  • 保留原有的选中/取消选中逻辑,确保点击日期时的交互正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 12:05:33