React Hook Form结合MUI Autocomplete与Zod验证问题求助
解决MUI Autocomplete + React Hook Form + Zod的表单值匹配问题
方案1:将选中选项的uuid作为表单值(匹配原Zod Schema)
通过React Hook Form的Controller组件适配MUI Autocomplete,实现存储uuid字符串、显示对应标签的需求,无需修改原有Zod校验规则:
<Controller name="collection" control={control} rules={{ required: "Collection is required" }} render={({ field: { onChange, value } }) => ( <Autocomplete options={collections} getOptionLabel={(option) => option.label} // 从选项列表中匹配当前表单值对应的完整对象 value={collections.find((item) => item.uuid === value) || null} // 选中时将uuid传给表单字段 onChange={(event, newValue) => { onChange(newValue ? newValue.uuid : null); }} renderInput={(params) => ( <TextField {...params} label="Collection" error={!!errors.collection} helperText={errors.collection?.message} variant="outlined" fullWidth /> )} /> )} />
设置后,React Hook Form的collection字段将存储选中项的uuid(字符串类型),完全匹配原有Zod Schema,同时Autocomplete正常显示选项标签。
方案2:修改Zod Schema接受对象值,提交时处理数据
若需直接存储选项对象,可调整Zod规则适配对象结构,提交时再提取uuid:
- 更新Zod Schema:
const formSchema = z.object({ collection: z.object({ uuid: z.string().uuid("Invalid UUID"), label: z.string().min(1, "Label is required") }) .nullable() .refine(val => val !== null, "Collection is required") });
- 调整Controller适配对象值:
<Controller name="collection" control={control} rules={{ required: "Collection is required" }} render={({ field: { onChange, value } }) => ( <Autocomplete options={collections} getOptionLabel={(option) => option.label} value={value || null} onChange={(event, newValue) => { onChange(newValue); }} renderInput={(params) => ( <TextField {...params} label="Collection" error={!!errors.collection} helperText={errors.collection?.message} variant="outlined" fullWidth /> )} /> )} />
- 提交时提取uuid:
const onSubmit = (data) => { const processedData = { ...data, collection: data.collection.uuid }; // 执行提交逻辑 };
关键提示
- 方案1无需修改校验规则,更贴合初始设计,优先推荐使用。
- 两种方案均通过
Controller的render属性适配Autocomplete,无需完全替换React Hook Form的默认事件处理。
内容的提问来源于stack exchange,提问作者Etoundi Oyono Georges Lévy
相关产品推荐
相关产品推荐

