react-calendar如何实现日期过滤并根据用户输入更新首个可选日期
问题排查与修复方案
核心故障原因
- 静态计算偏移天数:
singleDay、doubleDays在组件初始化时就完成计算,依赖的是初始的date状态,不会随勘察类型、当前时间动态更新,导致minDate计算错误。 - 未处理周末顺延逻辑:直接加1/2天之后如果刚好落在周六/周日,被
tileDisabled规则禁用后,日历会自动跳到下一个可用工作日,就会出现本该延后2天实际跳了多天的问题。 - 无兜底返回逻辑:
calcDays没有默认返回值,异常场景下可能导致minDate失效。
修复后代码
import { useState, useMemo } from 'react'; import Calendar from 'react-calendar'; // 工具函数:计算偏移N个工作日后的日期,跳过周末 const addWorkDays = (baseDate, daysOffset) => { let result = new Date(baseDate); let addedDays = 0; while (addedDays < daysOffset) { // 原生日期操作,无需额外依赖 result.setDate(result.getDate() + 1); // 0是周日,6是周六,跳过周末 if (result.getDay() !== 0 && result.getDay() !== 6) { addedDays++; } } return result; }; function AppointmentForm() { const [date, setDate] = useState(new Date()); const dateFormatted = format(date, "yyyy/MM/dd"); const dateSelected = date => { setDate(date); }; // 勘察类型状态 const [enquiryType, setEnquiryType] = useState('0'); const handleSelect = (event) => { const index = event.target.selectedIndex; const optionElement = event.target.childNodes[index]; const optionElementId = optionElement.getAttribute('id'); setEnquiryType(optionElementId); }; // 动态计算minDate,依赖勘察类型实时更新 const minDate = useMemo(() => { const now = new Date(); switch(enquiryType) { case '0': // 当天开始,自动跳过周末取第一个可用工作日 return addWorkDays(now, 0); case '1': // 1个工作日后 return addWorkDays(now, 1); case '2': // 2个工作日后 return addWorkDays(now, 2); default: return addWorkDays(now, 0); } }, [enquiryType]); return ( <Calendar tileDisabled={({ date }) => date.getDay() === 0 || date.getDay() === 6} prev2AriaLabel={null} prev2Label={null} next2Label={null} locale={null} showNeighboringMonth={false} minDetail="month" minDate={minDate} value={date} onClickDay={dateSelected} /> ) }
修改说明
- 新增
addWorkDays工具函数,计算偏移天数时自动跳过周末,避免出现minDate落在禁用日期的情况。 - 用
useMemo包裹minDate计算逻辑,依赖enquiryType实时更新,保证勘察类型切换后最小可选日期同步变更。 - 补充默认返回逻辑,避免异常值导致minDate失效。
内容的提问来源于stack exchange,提问作者Sam Lùc.
相关产品推荐
相关产品推荐

