Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Datepicker MomentJS Invalid Date

I'm using React-Datepicker and MomentJS. But when I want to use Moment for setting a startDate, the value gives Invalid date in the datepickerfield.

When I log the this.state.startDate in the console, the console shows me the following: "startdate: 27-11-2018", this has the format 'DD-MM-YYYY'. This format is also used for the DatePicker component.

import * as React from "react";
import * as ReactDOM from "react-dom";

import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import * as moment from "moment";
import "moment/locale/nl";

export class DateContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      startDate: moment().format('DD-MM-YYYY'),
    };
  }
  render() {
    console.log('startdate:',this.state.startDate);
    return (
        <div className="date-Filter">
          <div className="date-Filter-Title">Release Date</div>
          <DatePicker
            onChange={this.handleStartDate}
            selected={this.state.startDate}
            dateFormat="DD-MM-YYYY"
            isClearable={true}
            placeholderText="Select a date other than today or yesterday"
            fixedHeight={true}
            tetherConstraints={ [] }
            locale="nl"
            popperPlacement="right-start"
            popperModifiers={{
             flip: {
               enabled: false
             },
             preventOverflow: {
               enabled: true,
               escapeWithReference: false
             }
           }}
           selectsStart
           startDate={this.state.startDate}
           className="startDate"
           showMonthDropdown
           showYearDropdown
          />
        </div>
    );
  }
}

Can someone explain to me why it is showing invalid date in browser.

My Dependencies:

  "dependencies": {
    "moment": "^2.22.2",
    "react": "^16.6.0",
    "react-datepicker": "^2.0.0",
    "react-dom": "^16.6.0",
    "sass-loader": "^7.1.0",
    "searchkit": "^2.3.1-alpha.4"
  },
like image 685
Elvira Avatar asked Nov 27 '18 13:11

Elvira


3 Answers

Use startDate: moment().toDate().

.format('DD-MM-YYYY') returns a string, while the selected prop of the DatePicker react component requires a Date object.

like image 127
Anirudh Khanna Avatar answered Oct 19 '22 03:10

Anirudh Khanna


From Hacker0x01 - "Up until version 1.8.0, this package was using Moment.js. Starting v2.0.0, we switched to using native Date objects to reduce the size of the package. If you're switching from 1.8.0 to 2.0.0 or higher, please see the updated example above of check out the examples site for up to date examples."

https://github.com/Hacker0x01/react-datepicker

I am having a similar problem. I am going to try and turn the native Date into a moment after react-datepicker has done it's thing.

like image 3
Lance Crowder Avatar answered Oct 19 '22 04:10

Lance Crowder


@Elvira, i met the same challenge when using [email protected]. It is critical to follow any 3rd party packages that you make use of. The issue of modules as popularized by ES6 deemed moment.js an extra baggage in react-datepicker since moment.js is an all-in-one package i.e. import moment from 'moment';

The concept of modules enables us to make objects, functions, classes or variables available to the outside world by simply exporting them and then importing them where needed in other files.

Starting with [email protected], moment.js was removed as a dependency and the team started using the native javascript Date object paired with date-fns for all date functionality within the datepicker. Inspect propTypes of the react-datepicker calendar component, and you will notice that all dates are declared to be PropTypes.instanceOf(Date).

Solution: Stick to using the native JavaScript Date object. After a user selects a date from your calendar (read: react-datepicker), you can always convert that date object using moment.js to whatever format.

export class DateContainer extends React.Component {
  constructor(props) {
    super(props);
    // Used 'started' to avoid name conflicts, and return date object
    this.state = { started: new Date(), };
  }
  render() {
    const { started } = this.state
    return (
      // other jsx...
      <DatePicker
        // other props...
        selected={started}
        startDate={started}
      />
    );
  }
}

Below is how i went about dealing with this situation: Environment: [email protected], [email protected], [email protected], [email protected] and [email protected] (handling forms in react, made easy).

// stateless component
const InputForm = ({
  // other destructered props...
  dispatch = f => f
}) => {
  const values = {
    // initial state
  }

  return (
    <Formik
      // other props...
      onSubmit={
        async (values) => {
          // Here is my solution...
          // convert date object from react-datepicker using moment.js,
          // before i dispatch my state object.
          const userData = {
            ...values,
            start_date: moment(values.start_date).format('YYYY-MM-DD')
          }
          await dispatch(someAction(userData));
          // ...
        }
      }
    />
  )
};

export default connect()(InputForm);
like image 1
MwamiTovi Avatar answered Oct 19 '22 03:10

MwamiTovi