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

如何在React中创建嵌套分组表单并获取结构化提交值?

解决React嵌套表单层级结构化值问题

方法一:利用Antd Form的嵌套name路径(推荐)

Antd Form原生支持通过数组形式的name属性构建嵌套结构,无需额外自定义分组组件,直接让Form自动生成期望的嵌套对象。

示例代码

import { Form, Input, Button } from 'antd';

const NestedForm = () => {
  const onFinish = (values) => {
    console.log('提交的结构化值:', values);
    // 输出格式完全匹配需求:
    // {
    //   group1: {
    //     section1: { item1: 'xxx', item2: 'xxx' },
    //     section2: { item1: 'xxx', item2: 'xxx' }
    //   },
    //   group2: { ... }
    // }
  };

  return (
    <Form onFinish={onFinish}>
      {/* Group 1 区域 */}
      <div className="form-group">
        <h3>Group 1</h3>
        {/* Section 1 区域 */}
        <div className="form-section">
          <h4>Section 1</h4>
          <Form.Item
            name={['group1', 'section1', 'item1']}
            label="Item 1"
          >
            <Input />
          </Form.Item>
          <Form.Item
            name={['group1', 'section1', 'item2']}
            label="Item 2"
          >
            <Input />
          </Form.Item>
        </div>
        {/* Section 2 区域 */}
        <div className="form-section">
          <h4>Section 2</h4>
          <Form.Item
            name={['group1', 'section2', 'item1']}
            label="Item 1"
          >
            <Input />
          </Form.Item>
          <Form.Item
            name={['group1', 'section2', 'item2']}
            label="Item 2"
          >
            <Input />
          </Form.Item>
        </div>
      </div>

      {/* Group 2 区域 */}
      <div className="form-group">
        <h3>Group 2</h3>
        {/* Section 1 区域 */}
        <div className="form-section">
          <h4>Section 1</h4>
          <Form.Item
            name={['group2', 'section1', 'item1']}
            label="Item 1"
          >
            <Input />
          </Form.Item>
          <Form.Item
            name={['group2', 'section1', 'item2']}
            label="Item 2"
          >
            <Input />
          </Form.Item>
        </div>
        {/* Section 2 区域 */}
        <div className="form-section">
          <h4>Section 2</h4>
          <Form.Item
            name={['group2', 'section2', 'item1']}
            label="Item 1"
          >
            <Input />
          </Form.Item>
          <Form.Item
            name={['group2', 'section2', 'item2']}
            label="Item 2"
          >
            <Input />
          </Form.Item>
        </div>
      </div>

      <Form.Item>
        <Button type="primary" htmlType="submit">提交表单</Button>
      </Form.Item>
    </Form>
  );
};

export default NestedForm;

原理说明

Antd Form会解析数组形式的name,自动将字段值组装成嵌套对象,提交时直接获取结构化数据,无需额外处理。


方法二:自定义Context实现分组层级自动拼接

如果需要保留你最初的FormGroup/FormItem组件结构,可以通过React Context传递层级路径,让子组件自动拼接完整的字段名,完全贴合你的原始代码结构。

示例代码

import { createContext, useContext } from 'react';
import { Form, Input, Button } from 'antd';

// 创建层级上下文
const FormGroupContext = createContext([]);

// 自定义FormGroup组件,传递当前层级路径
const FormGroup = ({ name, children }) => {
  const parentPath = useContext(FormGroupContext);
  const currentPath = [...parentPath, name];
  return (
    <FormGroupContext.Provider value={currentPath}>
      <div>{children}</div>
    </FormGroupContext.Provider>
  );
};

// 自定义FormItem组件,自动拼接完整字段名
const FormItem = ({ name, label, children }) => {
  const parentPath = useContext(FormGroupContext);
  const fullName = [...parentPath, name];
  return (
    <Form.Item name={fullName} label={label}>
      {children}
    </Form.Item>
  );
};

const NestedForm = () => {
  const onFinish = (values) => {
    console.log('提交的结构化值:', values);
  };

  return (
    <Form onFinish={onFinish}>
      <FormGroup name="group1">
        <h3>Group 1</h3>
        <FormGroup name="section1">
          <h4>Section 1</h4>
          <FormItem name="item1" label="Item 1">
            <Input />
          </FormItem>
          <FormItem name="item2" label="Item 2">
            <Input />
          </FormItem>
        </FormGroup>
        <FormGroup name="section2">
          <h4>Section 2</h4>
          <FormItem name="item1" label="Item 1">
            <Input />
          </FormItem>
          <FormItem name="item2" label="Item 2">
            <Input />
          </FormItem>
        </FormGroup>
      </FormGroup>

      <FormGroup name="group2">
        <h3>Group 2</h3>
        <FormGroup name="section1">
          <h4>Section 1</h4>
          <FormItem name="item1" label="Item 1">
            <Input />
          </FormItem>
          <FormItem name="item2" label="Item 2">
            <Input />
          </FormItem>
        </FormGroup>
        <FormGroup name="section2">
          <h4>Section 2</h4>
          <FormItem name="item1" label="Item 1">
            <Input />
          </FormItem>
          <FormItem name="item2" label="Item 2">
            <Input />
          </FormItem>
        </FormGroup>
      </FormGroup>

      <Form.Item>
        <Button type="primary" htmlType="submit">提交表单</Button>
      </Form.Item>
    </Form>
  );
};

export default NestedForm;

原理说明

通过Context在FormGroup之间传递当前的层级路径,FormItem自动拼接父级路径和自身name,最终Antd Form根据完整的嵌套name生成结构化数据,完全匹配你的需求。


方法三:手动组装结构化数据(兼容现有代码)

如果不想修改现有组件结构,也可以在表单提交时,根据约定的字段名手动组装嵌套对象。

示例代码

import { Form, Input, Button } from 'antd';

const NestedForm = () => {
  const form = Form.useForm();

  const onFinish = () => {
    const rawValues = form.getFieldsValue();
    // 手动映射为嵌套结构
    const structuredValues = {
      group1: {
        section1: {
          item1: rawValues['group1-section1-item1'],
          item2: rawValues['group1-section1-item2'],
        },
        section2: {
          item1: rawValues['group1-section2-item1'],
          item2: rawValues['group1-section2-item2'],
        },
      },
      group2: {
        section1: {
          item1: rawValues['group2-section1-item1'],
          item2: rawValues['group2-section1-item2'],
        },
        section2: {
          item1: rawValues['group2-section2-item1'],
          item2: rawValues['group2-section2-item2'],
        },
      },
    };
    console.log('组装后的结构化值:', structuredValues);
  };

  return (
    <Form form={form} onFinish={onFinish}>
      <div className="form-group">
        <h3>Group 1</h3>
        <div className="form-section">
          <h4>Section 1</h4>
          <Form.Item name="group1-section1-item1" label="Item 1">
            <Input />
          </Form.Item>
          <Form.Item name="group1-section1-item2" label="Item 2">
            <Input />
          </Form.Item>
        </div>
        <div className="form-section">
          <h4>Section 2</h4>
          <Form.Item name="group1-section2-item1" label="Item 1">
            <Input />
          </Form.Item>
          <Form.Item name="group1-section2-item2" label="Item 2">
            <Input />
          </Form.Item>
        </div>
      </div>

      {/* Group 2 部分代码与Group 1类似 */}
      <div className="form-group">
        <h3>Group 2</h3>
        <div className="form-section">
          <h4>Section 1</h4>
          <Form.Item name="group2-section1-item1" label="Item 1">
            <Input />
          </Form.Item>
          <Form.Item name="group2-section1-item2" label="Item 2">
            <Input />
          </Form.Item>
        </div>
        <div className="form-section">
          <h4>Section 2</h4>
          <Form.Item name="group2-section2-item1" label="Item 1">
            <Input />
          </Form.Item>
          <Form.Item name="group2-section2-item2" label="Item 2">
            <Input />
          </Form.Item>
        </div>
      </div>

      <Form.Item>
        <Button type="primary" htmlType="submit">提交表单</Button>
      </Form.Item>
    </Form>
  );
};

export default NestedForm;

原理说明

通过给每个字段设置包含层级信息的唯一name(如group1-section1-item1),提交后手动将扁平的rawValues映射为嵌套对象,适合快速兼容现有代码的场景。


内容的提问来源于stack exchange,提问作者Yassine Hamadou

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 12:40:32