reactjs - React-datepicker med anpassad inmatning med manuell skrivning


Jag försöker skapa en react-datepicker-komponent med anpassad stil på inputfältet:

<DatePicker
        selected={startDate}
        customInput={<CustomInput inputRef={inputRef} />}
        onChangeRaw={(e) => handleChangeRaw(e)}
        onChange={(date: Date | null) => {
          setStartDate(date);
        }}
      />

const CustomInput = forwardRef((props: any, ref) => {
  return <Input {...props} ref={ref} />;
});

Jag ville införa validering (bara enkel validering så att det användaren skriver in kommer att formateras till datum, så att användaren inte kan skriva vad som helst).

Jag skapade en funktion som skulle formatera inmatningen med hjälp av onChangeRaw-attributet i react-datepicker:

  const handleChangeRaw = (date) => {
    date.currentTarget.value = format(startDate, "dd/MM/yyyy");
  };

Men efter att ha använt detta kan jag inte skriva längre. Någon som har en idé om hur man använder manuell inmatning med anpassad input i react-datepicker med en enkel valideringsfunktion?

Här är det återskapade problemet i sandlådan: https://codesandbox.io/s/react-datepicker-custominput-sample-forked-elx310?file=/src/App.tsx

Svar #1

selected={startDate}

Här förväntar sig react-datepicker ett Date-objekt.

Men när du utlöser handleChangeRaw får du ett ändringshändelse, med ett visst värde (date.currentTarget.value), men det är inte i datumnotationen som datepicker förväntar sig.

Så min syn på detta skulle vara;

  • onChangeRaw, konvertera inmatningsvärdet till ett nytt Date.
  • Om datumet inte är giltigt, ignorera bara ändringen
  • Annars, skapa ett nytt Date, och använd setStartDate för att ändra till det nya datumet
const handleChangeRaw = (date) => {
      const newRaw = new Date(date.currentTarget.value);
      if (newRaw instanceof Date && !isNaN(newRaw)) {
        setStartDate(newRaw);
      }
  };

Prova det online

Svar #2

Om jag förstår ditt problem korrekt kan du lägga till följande typ för att åtgärda typningen.

const handleChangeRaw = (date: React.FocusEvent<HTMLInputElement>) => {
    if (!startDate){
      return
    }
    date.currentTarget.value = format(startDate, "dd/MM/yyyy");
};

date bör ha typen React.FocusEvent<HTMLInputElement>. Eftersom startDate kan vara null, måste vi kontrollera innan vi använder det. I det här fallet returnerar jag bara från funktionen. Men du kan också tilldela ett standardvärde här eller något annat.