在Ant Design中,Form.List用于处理动态表单项,当需要用户输入多条结构相同的数据,并且这些数据的数量是动态变化时,可能需要嵌套使用Form.List。以下说明一种Form.List的嵌套方法。使用React函数组件的写法。
import { Form, Input, Button, Space } from 'antd';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
const Demo = () => {
const [form] = Form.useForm();
const onFinish = (values) => {
console.log('Received values of form: ', values);
};
return (
<Form
form={form}
onFinish={onFinish}
layout="vertical"
>
<Form.List name="items">
{(fields, { add, remove }) => (
<>
{fields.map((field) => (
<div key={field.key}>
<Form.List name={[field.name, 'subItems']}>
{(subFields, { add: addSub, remove: removeSub }) => (
<>
{subFields.map((subField, subIndex) => (
<Space key={subField.key} style={{ marginLeft: 24 }}>
<Form.Item
{...subField}
label={`Sub-item ${subIndex + 1}`}
name={[subField.name, 'subName']}
rules={[{ required: true, message: 'Missing sub-name' }]}
>
<Input placeholder="Sub-item Name" />
</Form.Item>
<MinusCircleOutlined onClick={() => removeSub(subField.name)} />
</Space>
))}
<Button type="dashed" onClick={() => addSub()} icon={<PlusOutlined />}>
Add Sub-item
</Button>
</>
)}
</Form.List>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</div>
))}
<Button type="dashed" onClick={() => add()}>
Add Item
</Button>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</>
)}
</Form.List>
</Form>
);
};
现在将内层和外层抽成两个函数组件:
(1)将函数内层抽出作为单独的函数组件,注意,要将内层Form.List包在一个Form.Item里面受控
const Inner = ({ field }) => {
return (
<Form.Item
{...field}
>
<Form.List name={[field.name, 'subItems']}>
{(subFields, { add: addSub, remove: removeSub }) => (
<>
{subFields.map((subField, subIndex) => (
<Space key={subField.key} style={{ marginLeft: 24 }}>
<Form.Item
{...subField}
label={`Sub-item ${subIndex + 1}`}
name={[subField.name, 'subName']}
rules={[{ required: true, message: 'Missing sub-name' }]}
>
<Input placeholder="Sub-item Name" />
</Form.Item>
<MinusCircleOutlined onClick={() => removeSub(subField.name)} />
</Space>
))}
<Button type="dashed" onClick={() => addSub()} icon={<PlusOutlined />}>
Add Sub-item
</Button>
</>
)}
</Form.List>
</Form.Item>
)
}
(2)之后改写外层组件:
import { Form, Input, Button, Space } from 'antd';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
const Outer = () => {
const [form] = Form.useForm();
const onFinish = (values) => {
console.log('Received values of form: ', values);
};
return (
<Form
form={form}
onFinish={onFinish}
layout="vertical"
>
<Form.List name="items">
{(fields, { add, remove }) => (
<>
{fields.map((field) => (
<div key={field.key}>
<Inner field={field} />
<MinusCircleOutlined onClick={() => remove(field.name)} />
</div>
))}
<Button type="dashed" onClick={() => add()}>
Add Item
</Button>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</>
)}
</Form.List>
</Form>
);
};
这样就可以内层Form.List抽出作为函数组件了。