如何在MUI DatePicker中使用react-hook-form的register方法?
问题原因
MUI的DatePicker系列组件属于封装后的自定义组件,没有完全遵循原生input的事件/值接口:
- 原生input的
onChange回调接收事件对象,从e.target.value取值 - MUI DatePicker的
onChange回调直接返回选中的Date对象/空值,不会返回事件对象
直接展开{...register("date")}会把register返回的适配原生input的onChange等属性注入组件,和组件本身的接口冲突,就会引发报错。
解决方案
方案1:使用Controller(官方推荐,适配所有自定义组件)
react-hook-form提供的Controller专门用来适配非原生输入组件,写法更稳定,也能完美对接Yup校验,不需要手动处理值同步、校验触发逻辑:
import { Controller, useForm } from 'react-hook-form'; import { KeyboardDatePicker } from '@material-ui/pickers'; import { yupResolver } from '@hookform/resolvers/yup'; import * as yup from 'yup'; // 表单初始化逻辑 const { control, handleSubmit, formState: { errors } } = useForm({ resolver: yupResolver(你的Yup校验Schema) }); // 组件渲染部分 <Controller name="date" control={control} defaultValue={null} // 可根据需求调整默认值 render={({ field: { onChange, value } }) => ( <KeyboardDatePicker variant="dialog" format="DD/MM/yyyy" value={value} onChange={onChange} id="date" error={Boolean(errors.date)} helperText={errors.date?.message} /> )} />
方案2:调整register属性映射(适合坚持用register写法的场景)
如果不想引入Controller,也可以手动拆分register返回的属性,适配DatePicker的接口:
const { register, setValue, formState: { errors } } = useForm({ resolver: yupResolver(你的Yup校验Schema) }); // 拆分register返回的ref和其他属性 const { ref, ...restRegister } = register("date"); <KeyboardDatePicker variant="dialog" format="DD/MM/yyyy" value={selectedDate} onChange={(date) => { // 手动同步选中的日期到表单 setValue("date", date, { shouldValidate: true }); }} id="date" name="date" inputRef={ref} // 绑定register返回的引用 error={Boolean(errors.date)} helperText={errors.date?.message} {...restRegister} />
内容的提问来源于stack exchange,提问作者Alan Shajan Mattathil
相关产品推荐
相关产品推荐

