Search code examples
reactjsreact-datepickerreact-hook-form

React Hook Form with datepicker Range doesn't pick date


I got the following datepickers.
For the Start Date:

<Controller
    as={
        <DatePicker
            selected={travelRoute?.dateStart || new Date()}
            selectsStart
            startDate={travelRoute?.dateStart}
            endDate={travelRoute?.dateEnd}
            inline
        />
    }
    control={control}
    rules={{ required: true }}
    valueName="selected"
    onChange={date => handleStartDateOnChange(date)}
    name="dateStart"
    placeholderText="Select date"
    defaultValue={null}
/>  

For the End Date:

<Controller
   as={
    <DatePicker
        name="dateEnd"
        selected={travelRoute?.dateEnd || new Date()}
        onChange={date => handleEndDateOnChange(date)}
        selectsEnd
        startDate={travelRoute?.dateStart}
        endDate={travelRoute?.dateEnd}
        minDate={travelRoute?.dateStart}
        inline
    />
   }
   control={control}
   rules={{ required: true }}
   valueName="selected"
   onChange={date => handleEndDateOnChange(date)}
   name="dateEnd"
   placeholderText="Select date"
   defaultValue={null}
/>  

Do I need to add the datepicker props to the datepicker component or to the Controller Component?
The start Datepicker doesn't select the date and the end Datepicker doesn't change the startdate and isn't displaying the range.

I'm saving the data into the travelRoute state with setTravelRoute which is happening in the handleOnChange functions.

EDIT:
Added onChange handler:

const handleStartDateOnChange = date => {
    setTravelRoute(prevState => ({
        ...prevState,
        dateStart: date
    }))
};

const handleEndDateOnChange = date => {
    setTravelRoute(prevState => ({
        ...prevState,
        dateEnd: date
    }))
};

Solution

  • Ciao, you are using the wrong approach to customize your onChange event in DatePicker. And onChange event on Controller can't work neihter. Because in this case, you don't have to use as= syntax, but render= syntax like:

    <Controller
        render={({ onChange }) => (
          <DatePicker
            ...
            onChange={date => handleStartDateOnChange(date)}
          />
        )}
        ...
      />
    

    So your code becomes:

    Start Date

    <Controller
        render={({ onChange }) => (
          <DatePicker
            selected={travelRoute?.dateStart || new Date()}
            selectsStart
            startDate={travelRoute?.dateStart}
            endDate={travelRoute?.dateEnd}
            inline
            onChange={date => handleStartDateOnChange(date)}
          />
        )}
        control={control}
        rules={{ required: true }}
        valueName="selected"
        name="dateStart"
        placeholderText="Select date"
        defaultValue={null}
      />
    

    End Date

    <Controller
        render={({ onChange }) => (
          <DatePicker
            name="dateEnd"
            selected={travelRoute?.dateEnd || new Date()}
            onChange={date => handleEndDateOnChange(date)}
            selectsEnd
            startDate={travelRoute?.dateStart}
            endDate={travelRoute?.dateEnd}
            minDate={travelRoute?.dateStart}
            inline
          />
        )}
        control={control}
        rules={{ required: true }}
        valueName="selected"
        name="dateEnd"
        placeholderText="Select date"
        defaultValue={null}
      />
    

    Here a working example.

    Note: I don't know why DatePicker in codesandbox looks so ugly. Could be the Controller because in this other codesandbox looks good.