
本文详解 react + typescript 项目中使用 react-hook-form 时表单提交后数据全为 undefined 的根本原因,并提供完整修复方案,包括 name 属性缺失、注册绑定要点及最佳实践。
本文详解 react + typescript 项目中使用 react-hook-form 时表单提交后数据全为 undefined 的根本原因,并提供完整修复方案,包括 name 属性缺失、注册绑定要点及最佳实践。
在使用 react-hook-form 构建 TypeScript 表单时,一个常见却极易被忽略的问题是:表单成功提交,但 handleSubmit 回调接收的 data 对象中所有字段值均为 undefined。这并非 Hook 失效,而是表单控件与 useForm 的双向绑定未正确建立。
核心原因在于:react-hook-form 依赖 HTML 表单元素的 name 属性作为唯一标识符,来映射和收集对应字段的值。即使你已调用 register('fieldName'),若 <Input>(或 <input>、<select> 等)缺失 name="fieldName" 属性,register 将无法将用户输入关联到表单状态,最终导致提交数据为空对象或全 undefined。
✅ 正确做法是:register 的参数必须与 DOM 元素的 name 属性严格一致。以下是修复后的关键代码片段:
<form onSubmit={handleSubmit(set_filter)}>
<FormGroup row className="pb-2">
<Label for="customerNameFilterText" sm={4}>
Customer Name
</Label>
<Col sm={8}>
<Input
{...register('customerNameFilterText')} // ✅ 注册字段名
name="customerNameFilterText" // ✅ 必须显式声明 name 属性
className="form-control"
placeholder="Search by Customer Name"
type="text"
/>
</Col>
</FormGroup>
{/* 其他字段同理:每个 Input 都需同时满足 register() 参数 === name 属性值 */}
<FormGroup check row>
<Row>
<Col sm={4}>
<Button className="view btn-secondary" type="button" onClick={reset}>
Clear Filters
</Button>
</Col>
<Col sm={4}></Col>
<Col sm={4}>
<Button className="btn-primary" type="submit">
Apply Filters
</Button>
</Col>
</Row>
</FormGroup>
</form>⚠️ 注意事项:
- name 属性不可省略:register() 返回的 props(如 onChange, onBlur, ref)虽能提升受控性,但 name 是 react-hook-form 内部数据收集的“键名”,缺之则绑定失效;
- 类型安全建议:为 FiltersProps 接口定义明确字段,确保 register() 字符串与之匹配,TypeScript 可辅助校验(例如使用 const { register } = useForm<FiltersProps>());
- 清除功能优化:Clear Filters 按钮建议绑定 reset() 方法(来自 useForm),而非仅手动重置 state,以同步表单内部状态与 UI;
- 调试技巧:可在 set_filter 中添加 console.log("raw data:", data) 并检查浏览器开发者工具的 Elements 面板,确认 <input> 元素是否真实渲染了 name 属性。
总结:react-hook-form 的数据流始于 name 属性 —— 它是连接 UI 输入与 JavaScript 数据的桥梁。只要确保每个受控字段的 name 值与 register() 参数完全一致,表单提交数据即可准确、可靠地传递至处理函数。


















