Eduardo Ribeiro
Eduardo Ribeiro

Reputation: 97

Custom react datepicker with typescript

I'm trying to create a custom datepicker following the instructions in documentation and after a long time I was able to do, but I'm still receiveing an error that says "Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?" I'm using typescript in my project.

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;

Upvotes: 5

Views: 10525

Answers (2)

Besufekad Tamiru
Besufekad Tamiru

Reputation: 126

If I understand your question correctly. In order to export your custom react-datepicker function. You can make use of the type { ReactDatePickerProps } from "react-datepicker" and you can customize this props type to your need. Here's CustomDatePicker Example to illustrate the idea.

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;

Upvotes: 1

natterstefan
natterstefan

Reputation: 443

yes, you need to use React.forwardRef to solve this issue. This is the code I came up with to solve this issue for me:

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

Upvotes: 0

Related Questions