You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:15:34