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

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;

问题演示:
日选项消失场景1
日选项消失场景2

解决思路

  • 处理日期合法性校验: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 22:58:11