React JS中未选开始日期时禁用结束日期选择器的代码排错
日期范围选择器交互实现方案
可行性说明
该交互完全可以实现,你编写的代码存在4处明显错误,会导致禁用逻辑、日期范围逻辑失效。
现有代码错误点
- 变量绑定错误:定义的
const startDate = new Date()是独立的固定值,既没有和表单的start_date字段做绑定,也不会在用户选择开始日期时更新,根本拿不到用户实际选中的开始日期 - 禁用判断逻辑失效:判断条件
startDate=== ""永远不成立,因为startDate初始化为Date对象,不可能等于空字符串,结束日期选择器永远不会进入禁用状态 - 最小日期取值异常:直接用固定的
startDate给结束日期设置minDate,初始状态下会把当前日期作为结束日期的最小可选值,和需求逻辑不符 - 缺少边界逻辑处理:如果用户先选了开始+结束日期,后续把开始日期改到比已选结束日期更晚的时间,会出现结束日期早于开始日期的逻辑错误
修正后代码
import { useForm, Controller } from 'react-hook-form'; import DatePicker from 'react-datepicker'; import moment from 'moment'; import 'react-datepicker/dist/react-datepicker.css'; export default function RangePicker() { const { control, watch, setValue } = useForm({ defaultValues: { start_date: null, end_date: null } }); // 实时监听开始日期的选中值 const currentStartDate = watch('start_date'); return ( <div className="date-picker-group"> <Controller control={control} name="start_date" render={({ field }) => ( <DatePicker placeholderText="MM/dd/yyyy" dateFormat="MM/dd/yyyy" onChange={(date) => { field.onChange(date); // 开始日期更新后,如果已选结束日期早于新的开始日期,清空结束日期 const currentEndDate = watch('end_date'); if (currentEndDate && date > currentEndDate) { setValue('end_date', null); } }} minDate={moment().toDate()} selected={field.value} id="start_dates" required autoComplete="off" onKeyDown={(e) => e.preventDefault()} /> )} /> <Controller control={control} name="end_date" render={({ field }) => ( <DatePicker placeholderText="MM/dd/yyyy" dateFormat="MM/dd/yyyy" onChange={(date) => field.onChange(date)} // 未选中开始日期时禁用结束选择器 disabled={!currentStartDate} // 结束日期最早只能选已选中的开始日期 minDate={currentStartDate} selected={field.value} autoComplete="off" onKeyDown={(e) => e.preventDefault()} /> )} /> </div> ); }
代码逻辑说明:使用react-hook-form自带的
watch方法实时获取开始日期的选中值,开始日期为null(未选择)时结束日期选择器自动禁用;选中开始日期后自动解禁,同时将结束日期的最小可选值设为已选的开始日期,避免选到早于开始日期的无效值。
内容的提问来源于stack exchange,提问作者Nidhi Mahajan
相关产品推荐
相关产品推荐

