reactjs - Selector de dată React personalizat cu TypeScript


Încerc să creez un selector de dată personalizat urmând instrucțiunile din documentație și după mult timp am reușit să fac asta, dar încă primesc o eroare care spune „Funcțiile componente nu pot primi referințe. Încercările de a accesa această referință vor eșua. Ai vrut să folosești React.forwardRef()?” Folosesc TypeScript în proiectul meu.

import DatePicker from "react-datepicker";
import React, { useContext, useState } from "react";
import "react-datepicker/dist/react-datepicker.css"; 
 
const Feed: React.FC = () => { 
 const [startDate, setStartDate] = useState();
  const ExampleCustomInput = ({
    value,
    onClick,
  }: {
    value?: any;
    onClick?: any;
  }) => (
    <DateFilter className="example-custom-input" onClick={onClick}>
      {value || "Escolha uma data"}
      <CalendarIcon />
    </DateFilter>
  );
  
    return (
    <Container>
      <LeftContent>
        <NewPost onClick={openModal}>+ Novo post</NewPost>
        <DatePicker
          dateFormat="dd/MM/yyyy"
          selected={startDate}
          onChange={(date: any) => setStartDate(date)}
          customInput={<ExampleCustomInput />}
        />
      </LeftContent>
    </Container>
  );
 };
 
 export default Feed;

Răspuns #1

Dacă înțeleg corect întrebarea ta. Pentru a exporta funcția ta personalizată react-datepicker, poți folosi tipul { ReactDatePickerProps } din "react-datepicker" și poți personaliza acest tip de props după nevoile tale. Iată un exemplu CustomDatePicker pentru a ilustra ideea.

type CustomDatePickerProps = ReactDatePickerProps & {t: Translate;};
const CustomDatePicker: React.FC<CustomDatePickerProps> = (props) => {
const { t, ...rest } = props;
      return (
<ReactDatePicker
  renderCustomHeader={({
    date,
    increaseYear,
    decreaseYear,
    decreaseMonth,
    increaseMonth,
    prevMonthButtonDisabled,
    nextMonthButtonDisabled,
    prevYearButtonDisabled,
    nextYearButtonDisabled,
  }) => (
    <div className="flex justify-between items-center px-3 py-2 ">
      <div className="flex">
        <button
          onClick={decreaseYear}
          disabled={prevYearButtonDisabled}
          className="text-textSecondary flex"
        >
          <LeftIcon className="w-4 h-4" />
          <LeftIcon className="w-4 h-4 -ml-3" />
        </button>
        <button
          onClick={decreaseMonth}
          disabled={prevMonthButtonDisabled}
          className="text-textSecondary  ml-1"
        >
          <LeftIcon className="w-4 h-4" />
        </button>
      </div>

      <div className="text-base font-bold">{`${numberToMonth(
        date.getMonth(),
        t
      )} ${date.getFullYear()}`}</div>

      <div className="flex">
        <button
          onClick={increaseMonth}
          disabled={nextMonthButtonDisabled}
          className="text-textSecondary"
        >
          <LeftIcon className="w-4 h-4 transform rotate-180" />
        </button>
        <button
          onClick={increaseYear}
          disabled={nextYearButtonDisabled}
          className="text-textSecondary flex ml-1"
        >
          <LeftIcon className="w-4 h-4 transform rotate-180" />
          <LeftIcon className="w-4 h-4 transform rotate-180 -ml-3" />
        </button>
      </div>
    </div>
  )}
  {...rest}
/>

); };

export default CustomDatePicker;

Răspunsul #2

da, trebuie să folosești React.forwardRef pentru a rezolva această problemă. Acesta este codul la care m-am gândit pentru a rezolva această problemă pentru mine:

import React, { FunctionComponent } from 'react'
import ReactDatePicker, { ReactDatePickerProps } from 'react-datepicker'

import 'react-datepicker/dist/react-datepicker.css'

const ReactDatePickerInput = React.forwardRef<
  HTMLInputElement,
  React.DetailedHTMLProps<
    React.InputHTMLAttributes<HTMLInputElement>,
    HTMLInputElement
  >
>((props, ref) => <input ref={ref} {...props} />)

ReactDatePickerInput.displayName = 'ReactDatePickerInput'

export const FormDatePicker: FunctionComponent<ReactDatePickerProps> = (props) => {
  return (
    <ReactDatePicker
      {...props}
      // @see https://github.com/Hacker0x01/react-datepicker/issues/862#issuecomment-534736357
      customInput={<ReactDatePickerInput label={label || ''} name={name} />}
    />
  )
}