在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抽出作為函數組件了。