Search code examples
reactjstypescriptreact-datepicker

React datepicker and typescript


Currently trying to use React and Typescript with react-datepicker.

I have a simple setup which I want to test, but I keep getting the following error:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object

Below is the file which uses the DatePicker package

import * as React from 'react';
import DatePicker from "react-datepicker";

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

interface DateConstructor  {
    startDate: Date;
} 

export class DateSelector extends React.Component<{}, DateConstructor > {
    constructor(props) {
        super(props);
        this.state = {
            startDate: new Date()
        };
    }

    private handleChange(date) {
        this.setState({
            startDate: date
        });
    }

    public render() {
        const { startDate } = this.state;
        return (
            <DatePicker 
                dateFormat="dd-mm-yyyy"
                selected={startDate} 
                onChange={this.handleChange}
            />
        )
    }
}

It seems very strange to me that the DatePicker package needs a string or function?

How to resolve this issue?

Full error below

Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
invariant
http://localhost:65273/dist/vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:118:15
ReactCompositeComponentWrapper.instantiateReactComponent
http://localhost:65273/dist/vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:20273:23
ReactCompositeComponentWrapper.performInitialMount
http://localhost:65273/dist/vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:29799:22
ReactCompositeComponentWrapper.mountComponent
http://localhost:65273/dist/vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:29690:21
Object.mountComponent
http://localhost:65273/dist/vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:12868:35
ReactCompositeComponentWrapper.performInitialMount
http://localhost:65273/dist/vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:29803:34
ReactCompositeComponentWrapper.mountComponent
http://localhost:65273/dist/vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:29690:21
Object.mountComponent
http://localhost:65273/dist/vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:12868:35
ReactCompositeComponentWrapper.performInitialMount
http://localhost:65273/dist/vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:29803:34
ReactCompositeComponentWrapper.mountComponent
http://localhost:65273/dist/vendor.js?v=OjVxDpV6p_Jfz2P38F_R2lc3pjVsUisUejeIABZq7AE:29690:21

Below is the file where I am trying to render the DateSelector component

import * as React from 'react';
import { RouteComponentProps } from 'react-router';

import { DataOutputSwitch } from './ComponentLibrary/DataOutputSwitch';
import { DatatypeSelector } from './ComponentLibrary/DatatypeSelector';
import { DateSelector } from './ComponentLibrary/DateSelector';


export class ComponentLibrary extends React.Component<RouteComponentProps<{}>, {}> {

    public render() {
        return (
            <div>
                <h1>Pair4Insights Component Library</h1>
                <p>This component demonstrates all separate components.</p>
                <div style={{display: 'flex', flexDirection: 'column'}}>
                    <h3>Data Output Switch</h3>
                    <DataOutputSwitch />
                    <h3>Datattype Selector</h3>
                    <DatatypeSelector datatype="revenue" />
                    <h3>Date Selector</h3>
                    <DateSelector />
                </div>
            </div>
        );
    }
}

Solution

  • I plugged this component to a working Typescript React application with minor modifications and it works without any problems. So I suspect this problem is caused by some factor other than this component. Does this error go away if you comment out this component and not import it?

    For reference' sake, here's the code:

    import * as React from 'react';
    import DatePicker from "react-datepicker";
    
    import "react-datepicker/dist/react-datepicker.css";
    
    interface DateConstructor  {
        startDate: Date;
    } 
    
    export class DateSelector extends React.Component<{}, DateConstructor> {
        constructor(props) {
            super(props);
            this.state = {
                startDate: new Date()
            };
            this.handleChange = this.handleChange.bind(this);
        }
    
        private handleChange(date) {
            console.log('date is here!', date);
            this.setState({
                startDate: date
            });
        }
    
        public render() {
            const { startDate } = this.state;
            return (
                <DatePicker
                    dateFormat="dd/MM/yyyy"
                    selected={startDate} 
                    onChange={this.handleChange}
                />
            )
        }
    }
    

    and the import at App.tsx:

    import { DateSelector } from './DateSelector';
    

    As you can see, few changes I've made are binding the handleChange function and updating the date formatting (at the question code, it's an incorrect input).

    recording-datepicker-gif

    I hope this answer have nudged you in the correct direction.