React-datepicker with a Formik form

I'm trying to use react-datepicker in a Formik form.

I have:

import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";


class Fuate extends React.Component {
    state = {
        dueDate: new Date()

    }

<Formik
                initialValues={initialValues}
                validationSchema={Yup.object().shape({
                    title: Yup.string().required("A title is required "),
                })}

                onSubmit={this.handleSubmit}

                render={({ 
                    errors, 
                    status, 
                    touched, 
                    setFieldValue,
                    setFieldTouched, 
                    handleChange, 
                    handleBlur,
                    handleSubmit, 
                    isSubmitting, 
                    dirty, 
                    values 
                }) => {

                return (
                    <div>
            ...

<DatePicker
                                            name={'dueDate'}
                                            value={values['dueDate']}
                                            onChange={e => setFieldValue('dueDate', e)}
                                        />
                                        <DatePicker
                                        style={{ width: 180 }}
                                        date={values.dueDate}
                                        mode="date"
                                        format="YYYY-MM-DD"
                                        minDate={Date.now.toString()}
                                        maxDate="2050-06-01"
                                        confirmBtnText="Confirm"
                                        cancelBtnText="Cancel"
                                        showIcon={false}
                                        customStyles={{
                                            dateInput: {
                                            marginLeft: 0,
                                            borderColor: "#fff"
                                            }
                                        }}
                                        onDateChange={date => setFieldValue("dueDate", date)}
                                        onTouch={setFieldTouched}
                                        />

For both of these options, the form renders, I can select a date on the calendar but it does not appear in the box and the state value is not updated with the selection.

There are no errors in the console, but the warning says:

Starting with v2.0.0-beta.1 date-fns doesn't accept strings as arguments. Please use parseISO to parse strings. See: toDate @ index.js:45

I tried making the initial state:

dueDate: new Date().toISOString(),

but it makes no difference.

I've seen lots of posts about setting this up with Antd's date picker, but can't find instructions for how to do it with react-datepicker.


Update to Dani Vijay's answer.
This uses useField and useFormikContext from Formik v2, to simplify usage of the component.

DatePicker.jsx:

import React from "react";
import { useField, useFormikContext } from "formik";
import DatePicker from "react-datepicker";

export const DatePickerField = ({ ...props }) => {
  const { setFieldValue } = useFormikContext();
  const [field] = useField(props);
  return (
    <DatePicker
      {...field}
      {...props}
      selected={(field.value && new Date(field.value)) || null}
      onChange={val => {
        setFieldValue(field.name, val);
      }}
    />
  );
};

Usage (see Dani's answer for the complete form declaration):

...
<DatePickerField name="date" />
...

Code at codesandbox


react-datepicker can used with Formik by utilising setFieldValue,

const DatePickerField = ({ name, value, onChange }) => {
    return (
        <DatePicker
            selected={(value && new Date(value)) || null}
            onChange={val => {
                onChange(name, val);
            }}
        />
    );
};

const App = () => (
    <Formik
        initialValues={{ date: "" }}
        ...
    >
        {props => {
            const {
                values,
                handleSubmit,
                setFieldValue
                ...
            } = props;
            return (
                <form onSubmit={handleSubmit}>
                    <DatePickerField
                        name="date"
                        value={values.date}
                        onChange={setFieldValue}
                    />
                    ...

CodeSandbox demo here


What I see from your code is DatePicker is not inside of Formik. In React.js we always create reusable components so keep the code clean and easy to test. To be able to use DatePicker in your code, create a separate file, write your code for Datepicker and render it as a component of the Field. here is how you should implement.

//First let's start with structure of Formik.
import PortDate from "./form/PortDate";
//define your components in a different directory. I named it form
const CreateForm = props => (
    <div>
      <Formik
        initialValues={{"your initial values"}}
        validate={your validation function here}
        onSubmit={values => {
          return props.onSubmit(values);
        }}
      >
        {({ isSubmitting }) => (
          <Form>     
            <Field name="startDate" component={DatePicker} label="Start Date" />

            <Field
              name="endDate"
              component={DatePicker}
              label="End Date"
              canBeDisabled={true}
            />

          </Form>
        )}
      </Formik>
    </div>
  );

now in a different component let's implement our Datepicker logic. //Use reactstrap instead of bootstrap when you want to add style

import { FormGroup, Label } from "reactstrap";
class DatePicker extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        dueDate: new Date(),
      };
      this.handleChange = this.handleChange.bind(this);
    }
    setFieldValueAndTouched(date, touched) {
      const { setFieldValue, setFieldTouched } = this.props.form;
      const { name } = this.props.field;
      setFieldValue(name, date, true); //field,value,shouldValidate
      setFieldTouched(name, touched, true); //field,touched,shouldValidate
    }
    handleChange(date) {

      this.setState(() => ({ dateValue: date }));
      this.setFieldValueAndTouched(date, true);    }

    render() {
      const { dueDate } = this.state;
      const {
        label,
        field,
        form: { touched, errors },
      } = this.props;
      // field and form props are passed to this component automatically because we render this inside component of the Field. 
      return (
        <FormGroup>
          <Label>{label}</Label>
          <div className="input-group">

              <DatePicker

                selected={dueDate}
                onChange={this.handleChange}
                peekNextMonth
                showMonthDropdown
                showYearDropdown
                maxDate={new Date()}
                dropdownMode="select"
              />

          </div>
        </FormGroup>
      );
    }
  }

  export default DatePicker;