react-dropdown-date组件异常:日-月-年格式下选择后天值消失
问题:react-dropdown-date 切换为 day->month->year 格式后日选项消失
使用react-dropdown-date组件实现日期选择功能时,year -> month -> day的顺序运行正常,但改为day -> month -> year的顺序后,出现异常:设置日和月后,日下拉菜单中的选中值会消失。
代码:
import ICustomField from '../../typings/ICostumField'; import React, {useEffect, useState} from 'react'; import {getInstanceError} from '../../utils/getInstanceError'; import {YearPicker, MonthPicker, DayPicker} from 'react-dropdown-date'; import { getUserDate } from '../../utils/utilsDate'; //getCorrectDate, const formatDate = (date) => { let d = new Date(date), day = '' + d.getDate(), month = '' + (d.getMonth() + 1), year = d.getFullYear(); if (day.length < 2) day = '0' + day; if (month.length < 2) month = '0' + month; return [year, month, day].join('-'); } const CustomField = ({register, errors, name, label, disabled, type = 'text', defaultValue = '', placeholder = '', styles = {}, setError, ...rest}: ICustomField) => { const [touch, setTouch] = useState(false); const [isOpen, setIsOpen] = useState(false); const [touchYear, setTouchYear] = useState(false); const [touchMonth, setTouchMonth] = useState(false); const [touchDay, setTouchDay] = useState(false); const [selectDate, setSelectDate] = useState<any>(null); const [year, setYear] = useState<any>(); const [month, setMonth] = useState<any>(); const [day, setDay] = useState<any>(); const minDate = new Date(); const maxDate = new Date(); minDate.setFullYear(maxDate.getFullYear() - 100); maxDate.setFullYear(maxDate.getFullYear() + 3); const { getMessageError, getClassError } = getInstanceError(errors); const handelBlur = () => { setTouch(true); }; useEffect(() => { if (year && month && day) { setSelectDate(new Date(year, month, day)); setIsOpen(false); } }, [year, month, day]); const mes = getMessageError(name); if (disabled) return null; return ( <div className={getClassError(name, touch)}> <label>{label}</label> {type !== 'date' && ( <input name={name} ref={register} type={type} placeholder={placeholder} onBlur={handelBlur} defaultValue={defaultValue} {...rest} /> )} {type === 'date' && ( <> <input name={name} ref={register} value={selectDate ? getUserDate(selectDate) : ''} onClick={() => setIsOpen(true)} onBlur={handelBlur} placeholder={placeholder} readOnly={true} /> {isOpen && <div className='dateDropDown-container-modal'> <div className='dateDropDown-close' onClick={() => setIsOpen(false)}>x</div> <DayPicker defaultValue={'День'} year={year} month={month} endYearGiven required={true} value={day} onChange={(day) => { setDay(day); setTouchDay(true); }} id={'day'} name={'day'} classes={touchDay ? 'dateDropDown-touch' : 'dateDropDown'} optionClasses={'dateDropDown-option'} /> <MonthPicker defaultValue={'Місяць'} numeric short caps endYearGiven year={year} required={true} value={month} onChange={(month) => { setMonth(month); setTouchMonth(true); }} id={'month'} name={'month'} classes={touchMonth ? 'dateDropDown-touch' : 'dateDropDown'} optionClasses={'dateDropDown-option'} /> <YearPicker defaultValue={'Рік'} start={+formatDate(minDate).split('-')[0]} end={+formatDate(maxDate).split('-')[0]} reverse required={true} value={year} onChange={(year) => { setYear(year); setTouchYear(true); }} id={'year'} name={'year'} classes={touchYear ? 'dateDropDown-touch' : 'dateDropDown'} optionClasses={'dateDropDown-option'} /> </div> } </> )} {mes && <p>{mes}</p>} </div> ) }; export default CustomField;
问题演示:

解决思路
处理日期合法性校验:react-dropdown-date的DayPicker依赖
year和month生成合法日期列表,当切换月份/年份后,若原选中的日超出新月份的最大天数,组件会自动清空日值。添加校验逻辑调整日值:useEffect(() => { if (year && month && day) { // 获取当前月份的最大天数 const maxDay = new Date(year, month, 0).getDate(); if (day > maxDay) { setDay(maxDay); } } }, [year, month]);限制选择顺序:在年份和月份未选中时,禁用日选择器,避免用户选择无效日期:
<DayPicker disabled={!year || !month} // 其他属性保持不变 />设置初始默认值:给年份和月份设置默认值(比如当前年份和月份),确保DayPicker初始化时能生成合法的日期列表:
const [year, setYear] = useState(new Date().getFullYear()); const [month, setMonth] = useState(new Date().getMonth() + 1);检查组件版本:尝试升级react-dropdown-date到最新版本,查看官方issue是否有同类问题的修复方案。
内容的提问来源于stack exchange,提问作者Hunter91151
相关产品推荐
相关产品推荐

