Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MUI X Date Picker with react-hook-form

I'm creating a form which has a date field. I'm using MUI and react-hook-form for validation. I've tried to render the field in two different ways, but when submitting my form I'm not getting the expected value:

Render 1

Using a Controller component:

const [originalReleaseDate, setOriginalReleaseDate] = useState(null);

<Controller
                                name={"original_release_date"}
                                defaultValue={originalReleaseDate}
                                control={control}
                                render={({field}) =>
                                    <LocalizationProvider dateAdapter={AdapterDateFns}>
                                        <DatePicker
                                            label="Original Release Date"
                                            value={originalReleaseDate}
                                            onChange={(newValue) => {
                                                setOriginalReleaseDate(newValue);
                                            }}

                                            renderInput={(params) =>
                                                <TextField
                                                    {...params}
                                                />}
                                        />
                                    </LocalizationProvider>
                            }
                            />

when I render the field this way, I'm getting null for original_release_date after submitting the form.

Render 2

Registering the field directly using {...register("reissue_release_date")} instead of react-hook-form Controlled component.

const [reissueReleaseDate, setReissueReleaseDate] = useState(null);

<LocalizationProvider dateAdapter={AdapterDateFns}>
                                <DatePicker
                                    label="Reissue Release Date"
                                    value={reissueReleaseDate}
                                    onChange={(newValue) => {
                                        setReissueReleaseDate(newValue);
                                    }}

                                    renderInput={(params) =>
                                        <TextField
                                            {...params}
                                            {...register("reissue_release_date")}
                                        />}
                                />
                            </LocalizationProvider>

this way is working half way. If I manually type the date then I'm getting its value on submit, BUT if I use the date picker and then submitting the form I get "".

Any idea what's going on?

like image 935
MrCujo Avatar asked Mar 10 '26 08:03

MrCujo


2 Answers

InputDate.propTypes = {
  name: PropTypes.string,
  label: PropTypes.string,
};
export default function InputDate({ name, label }) {
  const { control } = useFormContext();
  return (
    <Controller
      name={name}
      control={control}
      render={({ field: { onChange, value }, fieldState: { error } }) => (

        <LocalizationProvider dateAdapter={AdapterMoment} >
          <DesktopDatePicker
            label={label}
            control={control}
            inputFormat="DD-MM-YYYY"
            value={value}
            onChange={(event) => { onChange(event); }}
            renderInput={(params) => <TextField {...params} error={!!error} helperText={error?.message} />}
          />
        </LocalizationProvider>
      )} />
  )
}
like image 103
putu eka mulyana Avatar answered Mar 11 '26 20:03

putu eka mulyana


In most cases, if you are using react-hook-form, you don't need to track form fields with useState hook.

Using a Controller component is the right way to go. But there is a problem with onChange handler in your 1st method.

When you submit form, you are getting default date null because field is destructed, but it's not passed to DatePicker. So, onChange prop of field is not triggered when date is changed and react-hook-form doesn't have new date.

Here's how your render method should be

render={({field}) =>
     <LocalizationProvider dateAdapter={AdapterDateFns}>
          <DatePicker
              label="Original Release Date"
              renderInput={(params) =>
              <TextField
                   {...params}
              />}
              {...field}
          />
      </LocalizationProvider>
}

If for some reason, you need to update component state then you have to send data to react-hook-form and then update local state

render={({field: {onChange,...restField}) =>
         <LocalizationProvider dateAdapter={AdapterDateFns}>
              <DatePicker
                  label="Original Release Date"
                  onChange={(event) => {
                                            onChange(event);
                                            setOriginalReleaseDate(event.target.value);
                                        }}
                  renderInput={(params) =>
                  <TextField
                       {...params}
                  />}
                  {...restField}
              />
          </LocalizationProvider>
    }
like image 26
Sreekar Avatar answered Mar 11 '26 20:03

Sreekar