How to use react-datepicker <DatePicker /> properly with or without hook functions

1.7k views Asked by At

I'm coding with a React frontend, and while looking for a way to select days on a calendar, I came across a cool react module called "react-datepicker". This does practically everything I need. I'm trying to use the <DatePicker /> component as seen on the guide website: https://reactdatepicker.com/

What I'm having trouble with is the hook call. I can't seem to find a workaround for this hook call. When a user selects a date on the calendar, the date that is selected is placed as the value in the text-input. The way that this is done is with a hook call as seen in the website.

Now here's my issue. I would like to be able to use the onChange function that I've already written (if it's possible) that changes things on the webpage currently. It seems that there is an issue with hook calls being in functions outside the render() function call, as I get the error: Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component..., when I try to call the hook inside of my onChange function. Is there a work around for changing the text-input value for the DataPicker text input? Here's what my best attempt looks like right now:

import React, { Component, useState } from "react"; 
...
import DatePicker from 'react-datepicker';
...
export class AddEvent extends Component {
...
    onChange = (handleChange) => (e, e2) => {
        if (e2 == null && e != null) {
            this.setState({ [e.target.name]: e.target.value });
        } else if (e2 === null && e === null) {
            //The value I really want to show up in the text box is the one set here
            //It can be accessed for this example as this.state.days[0]
            this.setState({ ...this.state, "days": [null]});
            handleChange();
        } else {
            ...
            if ... {
            ...
            } else{
                //The value I really want to show up in the text box is the one set here
                //It can be accessed for this example as this.state.days[0]
                this.setState({ ...this.state, "days": [e] });
                handleChange();
            }
        }            
    }

    render() {
        //The value I really want to show up in the text box is the one in this.state.days[0]
        const minDate = new Date();
        const [aDate, setDate] = useState(minDate);
        const handleChange = date => setDate(date);

        return(
            <div className="mt-4 mb-4">
                <form onSubmit={this.onSubmit}>
                    ...
                    <div>
                        <label>Choose the Day(s) the Event could/will occur on:</label>
                        <DatePicker name="day1" onChange={this.onChange(handleChange)} minDate = {minDate} dateFormat="mm/dd/yyyy" />
                    </div>
                    ...
                </form>
            </div>
        );
    }
}
...
1

There are 1 answers

0
Robert On

Hooks are inclusive functionality restricted only to functional component. You can 'upgrade' your component to functional or just keep all your date on witch change component should be re-rendered in this.state and using this.setState to change it.

i'm not sure that i keep you business logic but you should doing this in that way:

import React, { Component, useState } from "react"; 

import DatePicker from 'react-datepicker';

export class AddEvent extends Component {
    state = {
      ///you stafff
      miDate : new Date(),
    }

    onChange = (e, e2) => {
       this.state(state => ({...state, miDate: e.target.value}));

        if (e2 == null && e != null) {
            this.setState({ [e.target.name]: e.target.value });
        } else if (e2 === null && e === null) {
            //The value I really want to show up in the text box is the one set here
            //It can be accessed for this example as this.state.days[0]
            this.setState({ ...this.state, "days": [null]});

        } else {

              this.setState({ ...this.state, "days": [e] });
        }            
    }

    render() {
        //!!! you can not use hooks in functional component !!!!!
        // const minDate = new Date();
        // const [aDate, setDate] = useState(minDate);
        // const handleChange = date => setDate(date);

        return(
            <div className="mt-4 mb-4">
                <form onSubmit={this.onSubmit}>
                    ...
                    <div>
                        <label>Choose the Day(s) the Event could/will occur on:</label>
                        <DatePicker name="day1" onChange={this.onChange.bind(this)} minDate = {this.state.minDate} dateFormat="mm/dd/yyyy" />
                    </div>
                    ...
                </form>
            </div>
        );
    }
}