如何在@mui/x-date-pickers v6中结合react-hook-form注册输入?
MUI X v6 DatePicker 与 react-hook-form 集成方案
在MUI X v6中,renderInput被移除后,直接在slotProps.textField中展开register的结果会引发事件冲突,因为DatePicker自身的onChange逻辑与react-hook-form的字段控制逻辑需要协调。以下是两种可行的解决方案:
方案一:使用Controller组件(推荐)
Controller是react-hook-form专门为复杂控件设计的包装组件,能自动处理值的同步与事件映射,避免手动适配的麻烦:
import { Controller } from 'react-hook-form'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; // 在你的表单组件内部 <Controller name="startDate" control={control} // control来自useForm的返回值 rules={{ required: true }} render={({ field: { onChange, value, name, ref } }) => ( <DatePicker label="Start Date" value={value} onChange={onChange} slotProps={{ textField: { name, inputRef: ref, // 可添加其他TextField属性,例如: variant="outlined" } }} /> )} />
说明:
Controller会将react-hook-form的字段状态(value)和事件(onChange)直接传递给DatePicker,自动处理Date对象与表单值的同步。inputRef用于将TextField的DOM引用绑定到react-hook-form,确保表单校验和焦点管理正常工作。
方案二:手动适配register与DatePicker事件
如果不想使用Controller,可以手动包装DatePicker的onChange事件,同时传递register返回的必要属性:
import { useForm } from 'react-hook-form'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; const { register, handleSubmit, formState: { errors } } = useForm(); // 包装DatePicker的onChange,适配register的事件格式 const handleDateChange = (date) => { register('startDate').onChange({ target: { name: 'startDate', value: date } }); }; // 获取register返回的onBlur和name属性 const { onBlur, name } = register('startDate', { required: true }); // 在组件中使用 <DatePicker label="Start Date" onChange={handleDateChange} slotProps={{ textField: { name, onBlur, // 手动处理错误提示 error: !!errors.startDate, helperText: errors.startDate ? 'Start date is required' : '' } }} />
说明:
- DatePicker的
onChange返回的是Date对象,而react-hook-form的register.onChange期望接收类似DOM事件的对象,因此需要手动包装。 - 必须传递
onBlur和name到TextField,确保表单的触发表单校验和字段识别正常。
注意事项
- 确保已正确配置MUI X的日期适配器(例如
@mui/x-date-pickers/AdapterDayjs),否则DatePicker无法正常渲染。 - 若使用方案一,需确保
control对象来自useForm的返回值。
内容的提问来源于stack exchange,提问作者Harsh Shah
相关产品推荐
相关产品推荐

