基于Material UI DateTimePicker实现已预约时段禁用
如何禁用DateTimePicker中特定日期的已预约时段
可以通过shouldDisableTime对应的disableSpecificTimes函数实现需求,以下是具体实现方案:
核心思路
shouldDisableTime函数虽仅接收timeValue(当天时分秒对应的时间戳)和clockType参数,但我们可以结合组件绑定的booking.bookingDate(当前选中的日期),将日期与待判断的时间拼接成完整的ISO格式时间字符串,再与timesBooked数组中的已预约时段对比,匹配则返回true禁用该时段。
具体实现代码
import dayjs from 'dayjs'; const disableSpecificTimes = (timeValue: number, clockType: ClockPickerView): boolean => { // 未选中日期时,暂不禁用任何时段 if (!booking.bookingDate) return false; // 提取选中日期的年月日部分 const selectedDateStr = dayjs(booking.bookingDate).format('YYYY-MM-DD'); // 将timeValue转换为时分格式(如09:00、15:30) const timeStr = dayjs(timeValue).format('HH:mm'); // 拼接成与timesBooked格式一致的完整时间字符串 const targetDateTime = `${selectedDateStr}T${timeStr}:00.000Z`; // 判断该时段是否已被预约,是则返回true禁用 return timesBooked.includes(targetDateTime); };
标记已禁用时段为红色
默认禁用的时间项为灰色,若要改成红色,可通过renderClockNumber属性自定义时间数字的渲染样式:
<DateTimePicker disablePast inputFormat="DD/MM/YYYY HH:mm" minutesStep={30} minTime={dayjs('2018-01-01T09:00')} maxTime={dayjs('2018-01-01T17:30')} renderDay={disableSpecificDays} shouldDisableDate={disableWeekends} shouldDisableTime={disableSpecificTimes} value={booking.bookingDate} onChange={(newValue) => { dispatch(b.setBookingDate(newValue)) }} renderInput={(params) => <TextField {...params} />} // 自定义时钟数字渲染 renderClockNumber={(clockNumber, selected, disabled, { clockType }) => { if (!booking.bookingDate) { return <span>{clockNumber}</span>; } const selectedDateStr = dayjs(booking.bookingDate).format('YYYY-MM-DD'); // 根据时钟类型(小时/分钟)拼接时间部分,因minutesStep为30,分钟仅00/30 const timeStr = clockType === 'hours' ? `${String(clockNumber).padStart(2, '0')}:00` : `${dayjs(booking.bookingDate).format('HH')}:${clockNumber === 0 ? '00' : '30'}`; const targetDateTime = `${selectedDateStr}T${timeStr}:00.000Z`; const isBooked = timesBooked.includes(targetDateTime); return ( <span style={{ color: isBooked ? 'red' : disabled ? '#aaa' : '#000', cursor: isBooked || disabled ? 'not-allowed' : 'pointer', padding: '4px', borderRadius: '4px' }} > {clockNumber} </span> ); }} />
注意事项
- 确保
booking.bookingDate是有效的dayjs实例,避免空值导致的格式转换错误 - 保证
timesBooked数组中的时间格式与代码中拼接的格式完全一致(YYYY-MM-DDTHH:mm:ss.000Z) - 切换日期时,组件会因
booking.bookingDate状态更新重新计算禁用时段,无需额外处理
内容的提问来源于stack exchange,提问作者Swansson
相关产品推荐
相关产品推荐

