React Hook Form传递control给自定义组件时显示undefined的解决方法
解决react-hook-form中control为undefined的问题
问题排查与修复步骤
1. 确认useForm初始化是否正确
你需要确保在FormProvider所在组件中,正确调用useForm生成methods对象。如果这一步缺失或错误,FormProvider无法传递有效上下文:
import { useForm, FormProvider } from "react-hook-form"; const YourFormComponent = () => { // 正确初始化表单方法 const methods = useForm(); // ...其他业务逻辑 return ( <FormProvider {...methods}> {/* 表单内容 */} </FormProvider> ); };
2. 移除TextField上错误的{...control}传递
control是react-hook-form的核心控制对象,不属于输入框的props,你在TextField中解构{...control}属于错误用法,直接删除该行:
// 修改前 <TextField fullWidth placeholder={/* ... */} sx={{ marginBlock: "1em" }} {...control} // 此行需删除 {...field} /> // 修改后 <TextField fullWidth placeholder={ filtered.ElsRecord.PersianName !== "" ? filtered.ElsRecord.PersianName : filtered.ElsRecord.Name } sx={{ marginBlock: "1em" }} {...field} />
3. 给Controller设置唯一的name属性
循环渲染CustomTextBoxComponent时,每个Controller的name都是"input"会导致字段冲突,甚至引发上下文异常。需基于filtered的唯一标识生成name:
<Controller // 用记录的唯一ID作为name的一部分,保证唯一性 name={`input_${filtered.ElsRecord.Id}`} render={({ field }) => ( <TextField fullWidth placeholder={ filtered.ElsRecord.PersianName !== "" ? filtered.ElsRecord.PersianName : filtered.ElsRecord.Name } sx={{ marginBlock: "1em" }} {...field} /> )} defaultValue="" />
4. 确认useFormContext引入正确
在CustomTextBoxComponent中需正确引入useFormContext:
import { useFormContext, Controller } from "react-hook-form";
5. 检查组件层级是否在FormProvider范围内
确保CustomTextBoxComponent没有被弹窗、Portal等组件带出FormProvider的层级。如果是通过Portal渲染的组件,需要单独处理上下文传递。
额外验证
若问题仍存在,可在CustomTextBoxComponent中打印上下文内容,确认是否获取到有效对象:
const CustomTextBoxComponent = ({ filtered }) => { const formContext = useFormContext(); console.log("Form Context:", formContext); // 查看是否包含control属性 const { control } = formContext; // ...其他逻辑 };
如果打印的formContext为undefined,说明组件不在FormProvider的上下文范围内,需重新检查层级结构。
内容的提问来源于stack exchange,提问作者sadsad
相关产品推荐
相关产品推荐

