Antd Form结合useRef遍历表单仅获最后值且值为undefined问题
问题描述
从API获取一组参考数据,需要为每条数据录入对应数量,使用Antd Form结合useRef实现,但提交时仅能获取最后一条表单的值,且部分值显示为undefined。
错误代码示例
逻辑部分
const formRef = useRef(); const submitFunction = (values) => { formRef.current.validateFields().then((values) => { console.log("Values:", values); }); };
渲染部分
{reference.map((e, index) => ( <Form ref={formRef} initialValues={{ ["Ref"]: e.reference }}> <div> <Row style={{ backgroundColor: "darkcyan" }} gutter={8}> <Col span={5}> <Form.Item label="Ref" name="Ref" labelCol={{ span: 6 }}> <Input key={index} defaultValue={e.reference} /> </Form.Item> </Col> <Col span={8}> <Form.Item name="quantity"> <InputNumber key={index} /> </Form.Item> </Col> <Col span={8}> <Form.Item> <Button onClick={() => submitFunction()}> click me </Button> </Form.Item> </Col> </Row> </div> </Form> ))}
问题根源
- 循环中重复创建多个
<Form>组件,且将同一个formRef绑定到所有Form上,最终formRef.current只会指向最后一个Form实例,因此只能获取最后一条数据的表单值。 - 所有Form的字段名均为
"Ref"和"quantity",未区分不同行的字段,同时initialValues与Input的defaultValue混用,导致部分值未正确绑定。 - 提交按钮分散在每个Form内部,点击时调用的函数仅能操作最后一个Form实例。
解决方案
使用单个Form包裹所有行,通过数组形式的字段名区分不同行的数据,确保所有数据被统一收集。
修正后代码示例
import { Form, Row, Col, Input, InputNumber, Button } from 'antd'; import { useRef } from 'react'; const YourComponent = () => { const formRef = useRef(); // 假设reference是从API获取的参考数据数组 const reference = [/* 你的API返回数据 */]; const submitFunction = () => { formRef.current.validateFields().then((values) => { console.log("所有表单值:", values.rows); }); }; return ( <Form ref={formRef} initialValues={{ // 统一初始化表单行数据 rows: reference.map(item => ({ Ref: item.reference, quantity: '' })) }} > {reference.map((e, index) => ( <Row key={index} style={{ backgroundColor: "darkcyan" }} gutter={8}> <Col span={5}> <Form.Item label="Ref" name={["rows", index, "Ref"]} labelCol={{ span: 6 }} > <Input disabled /> {/* 参考值设为禁用,避免误修改 */} </Form.Item> </Col> <Col span={8}> <Form.Item name={["rows", index, "quantity"]} rules={[{ required: true, message: '请输入数量' }]} > <InputNumber min={0} /> </Form.Item> </Col> </Row> ))} {/* 统一提交按钮 */} <Button onClick={submitFunction} type="primary" style={{ marginTop: 16 }}> 提交所有数据 </Button> </Form> ); }; export default YourComponent;
关键说明
- 单个Form包裹所有行,
formRef仅绑定一次,避免多实例冲突。 - 使用数组形式的
name属性["rows", index, "字段名"],Antd Form会自动将数据收集为数组values.rows,每个元素对应一行的完整数据。 - 通过
initialValues统一初始化表单,不再使用Input的defaultValue,避免数据绑定冲突。 - 提交按钮统一放在Form外部,点击时提交整个表单,一次性获取所有行的录入数据。
内容的提问来源于stack exchange,提问作者MeriemNAIM
相关产品推荐
相关产品推荐

