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

React Antd中如何让Input的addonAfter值与输入值合并提交?

问题:Antd Form.List动态组件提交时合并Input与addonAfter的Select值

在React Antd中使用Form.List动态添加多个带addonAfter(内嵌Select)的Input组件,提交表单后仅能获取输入框内容,期望将每个Input的输入值与对应Select的选中值合并后返回(例如输入test且选中.com,提交后得到test.com)。

现有代码

表单代码

<Form
  name="dynamic_form_nest_item"
  onFinish={onFinish}
  autoComplete="off"
>
  <Row gutter={16}>
    <Col span={12}>
      <Form.List name="domains">
        {(fields, { add, remove }) => (
          <>
            {fields.map(({ key, name, ...restField }) => {
              return (
                <Space
                  key={key}
                  style={{
                    display: "flex",
                    marginBottom: 8,
                  }}
                  align="baseline"
                >
                  <Form.Item {...restField} name={name}>
                    <Input
                      addonBefore="https://"
                      addonAfter={selectAfter}
                      defaultValue="mysite"
                    />
                  </Form.Item>
                  <MinusCircleOutlined onClick={() => remove(name)} />
                </Space>
              );
            })}
            <Form.Item>
              <Button
                type="dashed"
                onClick={() => add()}
                icon={<PlusOutlined />}
              >
                Add url
              </Button>
            </Form.Item>
          </>
        )}
      </Form.List>
    </Col>
  </Row>

  <Form.Item>
    <Button type="primary" htmlType="submit">
      Submit
    </Button>
  </Form.Item>
</Form>

selectAfter组件代码

const selectAfter = (
  <Select
    defaultValue=".com"
  >
    <Option value=".com">.com</Option>
    <Option value=".org">.org</Option>
  </Select>
);

当前提交结果为['test', 'test2'],期望得到['test.com', 'test2.org']。


解决方向

方案1:将每个条目改为嵌套字段,分别管控输入值与后缀

核心思路是让Select也被Form管控,每个动态条目存储一个包含输入值和后缀的对象,提交时再将两者拼接。

  1. 修改动态条目结构:
    将每个Form.Item的name改为数组形式,分别绑定输入值和后缀字段,同时每个条目独立渲染Select避免状态共享:

    {fields.map(({ key, name, ...restField }) => {
      return (
        <Space
          key={key}
          style={{ display: "flex", marginBottom: 8 }}
          align="baseline"
        >
          <Input.Group compact>
            <Form.Item
              {...restField}
              name={[name, 'input']}
              noStyle
            >
              <Input addonBefore="https://" defaultValue="mysite" />
            </Form.Item>
            <Form.Item
              {...restField}
              name={[name, 'suffix']}
              noStyle
            >
              <Select defaultValue=".com">
                <Option value=".com">.com</Option>
                <Option value=".org">.org</Option>
              </Select>
            </Form.Item>
          </Input.Group>
          <MinusCircleOutlined onClick={() => remove(name)} />
        </Space>
      );
    })}
    
  2. 在onFinish中合并数据:
    提交时遍历表单返回的domains数组,将每个对象的input和suffix拼接:

    const onFinish = (values) => {
      const mergedDomains = values.domains.map(item => `${item.input}${item.suffix}`);
      console.log('处理后的数据:', mergedDomains);
      // 后续业务逻辑使用mergedDomains即可
    };
    

方案2:使用Form的transform属性直接转换提交数据

如果不想修改表单结构,可以通过Form的transform属性在提交阶段直接处理数据,但需要手动维护每个Select的选中状态(比如用useState存储所有后缀值),不过方案1更符合Antd Form的管控逻辑,推荐优先使用。


内容的提问来源于stack exchange,提问作者Casper Karlsson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:05:33