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

如何在提交预订后禁用Material UI日历中的已选日期

解决Material UI DateTimePicker禁用已预订日期的问题

我在React应用的表单中集成了Material UI Date & Time picker做预订系统,用户可以选择日期时间并提交姓名、邮箱。需求是提交后的日期时间存入数组,后续用户选到这些日期时,日历要禁用它们避免重复预订。尝试用shouldDisableDate方法但遇到瓶颈,代码如下:

import React, {useState } from "react";

import DateFnsUtils from '@date-io/date-fns';
import { DateTimePicker, MuiPickersUtilsProvider} from "@material-ui/pickers";

function Booking() {

  const [selectedDate, handleDateChange] = useState(new Date());
  const [calendarData, setCalendardata] = useState([]);
  console.log(calendarData);
  console.log(selectedDate);

  let stringfySelectedDate = JSON.stringify(selectedDate);

  const onSubmitDate = (e) => {
    e.preventdefault();
    
    // If the the array length is === to zero then add the first element
    if(calendarData.length === 0) {
      setCalendardata([...calendarData, stringfySelectedDate]);
      console.log("empty array");
    }

    if(calendarData.includes(stringfySelectedDate)) {
      console.log("already exist");
      return calendarData;
    } else {
      setCalendardata([...calendarData, JSON.stringify(selectedDate)]);
    }
  
  }

  
  return (
    <>
    <MuiPickersUtilsProvider utils={DateFnsUtils}>
      <DateTimePicker
        label="Book"
        inputVariant="outlined"
        value={selectedDate}
        onChange={handleDateChange}
        shouldDisableDate={}
        disablePast
        showTodayButton
        clearable
        id="calendar"
      />
    </MuiPickersUtilsProvider>
    <div className="col-12">
                          <div className="text-center">
                            <button
                              onClick={onSubmitDate}
                              className="nb butn light mt-30 full-width"
                            >
                              <span className="ls3 text-u">click</span>
                            </button>
                          </div>
                        </div>
    </>
  );
}

export default Booking;

问题分析与修复步骤

  1. 修正提交函数拼写错误
    原代码里e.preventdefault()是小写的d,应该改为e.preventDefault(),否则阻止默认行为无效。

  2. 优化日期存储格式
    用JSON.stringify存储日期会带来时区、精度不一致的问题,建议把日期转成ISO标准字符串(比如selectedDate.toISOString())或者统一格式的时间字符串,保证对比时的准确性。

  3. 实现shouldDisableDate方法
    这个方法接收一个date参数,我们需要把这个参数转成和存储的日期一致的格式,然后判断是否在已预订数组中,返回true就会禁用该日期。

  4. 简化提交逻辑
    原代码的判断逻辑冗余,不需要单独处理空数组的情况,直接判断当前选中的日期是否已存在,不存在就添加到数组。


修改后的完整代码

import React, { useState } from "react";

import DateFnsUtils from '@date-io/date-fns';
import { DateTimePicker, MuiPickersUtilsProvider} from "@material-ui/pickers";

function Booking() {
  const [selectedDate, handleDateChange] = useState(new Date());
  const [bookedDates, setBookedDates] = useState([]);

  // 统一日期格式为ISO字符串,避免对比误差
  const formatDate = (date) => date.toISOString();

  const onSubmitDate = (e) => {
    e.preventDefault();
    const formattedSelectedDate = formatDate(selectedDate);

    // 检查日期是否已预订,未预订则添加
    if (!bookedDates.includes(formattedSelectedDate)) {
      setBookedDates([...bookedDates, formattedSelectedDate]);
    } else {
      console.log("该日期已被预订");
    }
  };

  // 实现禁用已预订日期的逻辑
  const shouldDisableDate = (date) => {
    const formattedDate = formatDate(date);
    return bookedDates.includes(formattedDate);
  };

  return (
    <>
      <MuiPickersUtilsProvider utils={DateFnsUtils}>
        <DateTimePicker
          label="Book"
          inputVariant="outlined"
          value={selectedDate}
          onChange={handleDateChange}
          shouldDisableDate={shouldDisableDate}
          disablePast
          showTodayButton
          clearable
          id="calendar"
        />
      </MuiPickersUtilsProvider>
      <div className="col-12">
        <div className="text-center">
          <button
            onClick={onSubmitDate}
            className="nb butn light mt-30 full-width"
          >
            <span className="ls3 text-u">提交预订</span>
          </button>
        </div>
      </div>
    </>
  );
}

export default Booking;

关键说明

  • formatDate函数统一日期格式,避免因时区或日期对象的差异导致对比失败
  • shouldDisableDate方法会在日历渲染每个日期时调用,返回true就会禁用该日期
  • 提交逻辑简化后,只需要判断日期是否已存在,不存在就添加到已预订数组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:20:28