You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 21:30:50