- Published on
How to Use Material-UI DatePicker with react-hook-form
- Authors
- Name
- Ripal & Zalak
How to Use Material-UI DatePicker with react-hook-form
Integrating Material-UI (MUI) DatePicker with react-hook-form can be tricky, especially when dealing with controlled vs uncontrolled components. In this guide, we'll explore the best practices to correctly handle date values while ensuring proper form validation.
Why Use react-hook-form with MUI DatePicker?
- Performance-friendly:
react-hook-formreduces unnecessary re-renders. - Simplifies validation: Easy integration with Yup or custom validation rules.
- Supports controlled components: Ensures MUI DatePicker works seamlessly with form state.
Common Issues and Fixes
Before we dive into solutions, let’s examine common issues developers face:
❌ Issue 1: Controller not updating the form value
If you use MUI DatePicker inside a Controller but don’t properly pass field.onChange, your form won’t register changes.
❌ Issue 2: register() doesn’t work with DatePicker
Using register() directly with DatePicker leads to issues since DatePicker doesn’t emit an event like typical inputs.
✅ Solution: Use Controller to manage DatePicker
Implementing MUI DatePicker with react-hook-form
1️⃣ Basic Setup
Ensure you have the necessary dependencies:
npm install @mui/lab @mui/material @mui/x-date-pickers date-fns react-hook-form
2️⃣ Controlled Component with Controller
import React from 'react'
import { useForm, Controller } from 'react-hook-form'
import { LocalizationProvider, DatePicker } from '@mui/x-date-pickers'
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'
import { TextField, Button } from '@mui/material'
export default function DatePickerForm() {
const { control, handleSubmit } = useForm()
const onSubmit = (data) => {
console.log(data)
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Controller
name="date"
control={control}
defaultValue={null}
render={({ field: { onChange, value }, fieldState: { error } }) => (
<DatePicker
label="Select Date"
value={value}
onChange={onChange}
renderInput={(params) => (
<TextField {...params} error={!!error} helperText={error?.message} />
)}
/>
)}
/>
</LocalizationProvider>
<Button type="submit" variant="contained">
Submit
</Button>
</form>
)
}
3️⃣ Handling Validations
You can easily add validation rules using rules in Controller:
<Controller
name="date"
control={control}
rules={{ required: 'Date is required' }}
render={({ field, fieldState: { error } }) => (
<DatePicker
label="Select Date"
value={field.value}
onChange={field.onChange}
renderInput={(params) => (
<TextField {...params} error={!!error} helperText={error?.message} />
)}
/>
)}
/>
4️⃣ Handling Default Values and State Updates
If you want to set a default date:
const { control } = useForm({
defaultValues: { date: new Date() },
})
This ensures that DatePicker is initialized with a value and avoids uncontrolled component warnings.
FAQ
1️⃣ Why is my DatePicker value null on form submit?
Ensure you are using Controller and passing onChange correctly inside the render method.
2️⃣ Can I use register() instead of Controller?
No, register() works for basic inputs, but DatePicker requires Controller since it doesn’t emit native change events.
3️⃣ How can I use react-hook-form validation with DatePicker?
Use the rules prop inside Controller to enforce validation rules like required fields.
