如何让MUI X v5 DatePicker返回Date类型以适配Zod与React Hook Form校验?
MUI X v5 DatePicker结合Zod与React Hook Form校验失败的解决方法
问题核心:你使用Dayjs适配器时,DatePicker返回的是Dayjs对象,而Zod的z.date()仅校验原生Date类型,因此导致校验始终失败。以下是两种可行的解决方式:
方法一:在onChange回调中手动转换类型
修改DatePicker的onChange方法,将选中的Dayjs对象转换为原生Date后再传给React Hook Form的field.onChange:
<Controller name={id} control={control} defaultValue={defaultValue?.toDate()} // 默认值同步转换为原生Date render={({ field: { ref, ...field } }) => ( <LocalizationProvider dateAdapter={AdapterDayjs}> <DatePicker label={label} value={field.value ? dayjs(field.value) : null} // 将原生Date转回Dayjs适配DatePicker onChange={(value) => field.onChange(value?.toDate())} maxDate={maxDate && maxDate} minDate={minDate && minDate} renderInput={(params) => ( <TextField inputRef={ref} required={required} {...params} fullWidth size="small" error={!!errors[id]} helperText={errors[id]?.message?.toString()} {...field} /> )} /> </LocalizationProvider> )} />
方法二:使用Controller的transform属性自动转换
借助React Hook Form Controller的transform选项,自动将Dayjs对象转换为原生Date类型,无需修改onChange逻辑:
<Controller name={id} control={control} defaultValue={defaultValue?.toDate()} // 默认值同步转换为原生Date transform={(value) => value?.toDate()} // 自动转换传入表单的值 render={({ field: { ref, ...field } }) => ( <LocalizationProvider dateAdapter={AdapterDayjs}> <DatePicker label={label} value={field.value ? dayjs(field.value) : null} // 将原生Date转回Dayjs适配DatePicker onChange={(value) => field.onChange(value)} maxDate={maxDate && maxDate} minDate={minDate && minDate} renderInput={(params) => ( <TextField inputRef={ref} required={required} {...params} fullWidth size="small" error={!!errors[id]} helperText={errors[id]?.message?.toString()} {...field} /> )} /> </LocalizationProvider> )} />
补充说明
- 无论采用哪种方法,defaultValue必须是原生Date类型,如果原本是Dayjs对象,需调用
.toDate()完成转换。 - DatePicker的
value字段需要Dayjs类型,因此要把React Hook Form存储的原生Date转回Dayjs(dayjs(field.value)),避免组件显示异常。
内容的提问来源于stack exchange,提问作者Breldan
相关产品推荐
相关产品推荐

