react-hook-form无法校验带defaultValue的react-select控件问题
问题根因
这个问题是react-hook-form结合react-select封装时的典型配置问题,核心原因是react-select的选中值结构、react-hook-form的字段存储值结构、校验规则预期结构三者不匹配,或者初始默认值没有正确同步到react-hook-form的校验状态池。
对应解决方案
1. 统一值结构(最常见场景)
react-select默认接收/返回的选中值是和选项一致的{label: string, value: any}结构,如果你的表单defaultValues里对应字段只存了原始值(比如仅存value字段的字符串/数字),就会出现初始校验识别不到有效值的问题:
- 优先在表单初始化的
defaultValues中直接传入完整的{label, value}结构值,和react-select的返回结构对齐:
const { control, trigger } = useForm({ defaultValues: { // 错误写法:selectField: '1' selectField: { label: '默认选项', value: '1' } } })
- 如果业务逻辑要求只能存储原始值,需要在
Controller的render回调中做双向映射:
<Controller name="selectField" control={control} rules={{ required: '请选择选项' }} render={({ field }) => ( <Select options={yourOptions} // 把form存储的原始值映射为react-select需要的option结构 value={yourOptions.find(opt => opt.value === field.value)} // 选择时仅把value原始值回传给form onChange={(val) => field.onChange(val?.value)} onBlur={field.onBlur} /> )} />
2. 修正字段绑定逻辑
不要给react-select单独设置defaultValue属性,所有默认值统一由react-hook-form的defaultValues声明,通过Controller自动同步,避免两边默认值不一致导致的状态断层。
3. 对齐校验规则
如果使用zod/yup等校验schema,需要确保规则和字段存储的结构匹配:
- 存完整
{label, value}对象时,校验规则要对应声明对象结构:
const formSchema = z.object({ selectField: z.object({ label: z.string(), value: z.string() }, { required_error: '请选择选项' }) })
- 存原始值时,直接校验对应类型的非空即可:
const formSchema = z.object({ selectField: z.string({ required_error: '请选择选项' }).nonempty() })
内容的提问来源于stack exchange,提问作者Dennis
相关产品推荐
相关产品推荐

