react-dropdown-date 问题与日期

问题描述 投票:0回答:1

我使用react-dropdown-date组件来选择日期。当格式如下时它效果很好:

year -> month -> day
但是当我想更改 exmaple 的格式时:
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;

截图:

有什么想法可以解决这个问题吗?谢谢。

javascript reactjs typescript datepicker dropdown
1个回答
0
投票

根据您的代码,问题似乎可能与如何管理日、月和年值的状态有关。由于下拉菜单的顺序已更改,您需要相应地调整状态更新。

这里对 DayPicker、MonthPicker 和 YearPicker 组件中的 onChange 处理程序进行了修改,以处理新顺序(“日 -> 月 -> 年”)中的更改:

// ...

<DayPicker
  // ...
  onChange={(day) => {
    setDay(day);
    setTouchDay(true);

    if (month !== undefined && year !== undefined) {
      setSelectDate(new Date(year, month, day));
      setIsOpen(false);
    }
  }}
  // ...
/>

<MonthPicker
  // ...
  onChange={(month) => {
    setMonth(month);
    setTouchMonth(true);

    if (day !== undefined && year !== undefined) {
      setSelectDate(new Date(year, month, day));
      setIsOpen(false);
    }
  }}
  // ...
/>

<YearPicker
  // ...
  onChange={(year) => {
    setYear(year);
    setTouchYear(true);

    if (day !== undefined && month !== undefined) {
      setSelectDate(new Date(year, month, day));
      setIsOpen(false);
    }
  }}
  // ...
/>

// ...

通过在更新 selectDate 并关闭下拉列表之前检查是否定义了所有三个值(日、月和年),可以确保在更改格式时正确更新日期值。

请记住用这些修改后的 onChange 处理程序替换现有代码的相应部分。

此外,请确保其余代码(包括 CSS 类和样式)能够很好地适应新格式。

© www.soinside.com 2019 - 2024. All rights reserved.