reactjs - React-datepicker med tilpasset input med manuell typing


Jeg prøver å lage en react-datepicker-komponent med egendefinert stylet input:

<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} />;
});

Jeg ønsket å introdusere validering (bare enkel validering slik at uansett hva brukeren skriver inn vil bli formatert til dato, så brukeren ikke kan skrive hva som helst).

Jeg opprettet en funksjon som ville formatere inputen ved å bruke onChangeRaw-attributtet i react-datepicker:

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

Men etter å ha brukt dette kan jeg ikke skrive mer. Har noen noen idé om hvordan man kan bruke manuell skriving med tilpasset input i react-datepicker med enkel valideringsfunksjon?

Her er gjenskapt problem i sandkassen: https://codesandbox.io/s/react-datepicker-custominput-sample-forked-elx310?file=/src/App.tsx

Svar #1

selected={startDate}

Her forventer react-datepicker et Date-objekt.

Men når du utløser handleChangeRaw, får du en endringshendelse, med en viss verdi (date.currentTarget.value), men det er ikke i datonotasjonen som datovelgeren forventer.

Så min mening om dette ville være;

  • onChangeRaw, konverter inndataverdien til en ny Date.
  • Hvis datoen ikke er gyldig, bare ignorér endringen
  • Ellers, opprett en ny Date, og bruk setStartDate for å endre til den nye datoen
const handleChangeRaw = (date) => {
      const newRaw = new Date(date.currentTarget.value);
      if (newRaw instanceof Date && !isNaN(newRaw)) {
        setStartDate(newRaw);
      }
  };

Prøv det på nett

Svar #2

Hvis jeg forstår problemet ditt riktig, kan du legge til følgende type for å fikse typingen.

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>. Siden startDate kan være null, må vi sjekke før vi bruker den. I dette tilfellet returnerer jeg bare fra funksjonen. Men du kan også tilordne en standardverdi her eller noe annet.