2019-07-03 20:14:39 +08:00
---
order: 8
title:
zh-CN: 多表单联动
en-US: Control between forms
---
## zh-CN
通过 `Form.Provider` 在表单间处理数据。本例子中, Modal 的确认按钮在 Form 之外,通过 `form.submit` 方法调用表单提交功能。反之,则推荐使用 `<Button htmlType="submit" />` 调用 web 原生提交逻辑。
## en-US
Use `Form.Provider` to process data between forms. In this case, submit button is in the Modal which is out of Form. You can use `form.submit` to submit form. Besides, we recommend native `<Button htmlType="submit" />` to submit a form.
```tsx
2019-11-29 16:36:33 +08:00
import { SmileOutlined, UserOutlined } from '@ant-design/icons';
2022-05-23 14:37:16 +08:00
import { Avatar, Button, Form, Input, InputNumber, Modal, Typography } from 'antd';
2022-05-19 09:46:26 +08:00
import type { FormInstance } from 'antd/es/form';
2022-05-23 14:37:16 +08:00
import React, { useEffect, useRef, useState } from 'react';
2019-07-03 20:14:39 +08:00
const layout = {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
};
const tailLayout = {
wrapperCol: { offset: 8, span: 16 },
};
2020-12-17 15:09:18 +08:00
interface UserType {
name: string;
age: string;
}
2019-07-03 20:14:39 +08:00
interface ModalFormProps {
2022-08-23 16:55:57 +08:00
open: boolean;
2019-07-03 20:14:39 +08:00
onCancel: () => void;
}
2020-03-22 18:31:05 +08:00
// reset form fields when modal is form, closed
2022-08-23 16:55:57 +08:00
const useResetFormOnCloseModal = ({ form, open }: { form: FormInstance; open: boolean }) => {
const prevOpenRef = useRef< boolean > ();
2020-01-22 12:11:49 +08:00
useEffect(() => {
2022-08-23 16:55:57 +08:00
prevOpenRef.current = open;
}, [open]);
const prevOpen = prevOpenRef.current;
2020-02-25 16:21:24 +08:00
useEffect(() => {
2022-08-23 16:55:57 +08:00
if (!open & & prevOpen) {
2020-02-25 16:21:24 +08:00
form.resetFields();
}
2022-08-23 16:55:57 +08:00
}, [form, prevOpen, open]);
2020-03-22 18:31:05 +08:00
};
2022-08-23 16:55:57 +08:00
const ModalForm: React.FC< ModalFormProps > = ({ open, onCancel }) => {
2020-03-22 18:31:05 +08:00
const [form] = Form.useForm();
useResetFormOnCloseModal({
form,
2022-08-23 16:55:57 +08:00
open,
2020-03-22 18:31:05 +08:00
});
2019-07-03 20:14:39 +08:00
const onOk = () => {
form.submit();
};
return (
2022-08-23 16:55:57 +08:00
< Modal title = "Basic Drawer" open = {open} onOk = {onOk} onCancel = {onCancel} >
2019-07-03 20:14:39 +08:00
< Form form = {form} layout = "vertical" name = "userForm" >
< Form.Item name = "name" label = "User Name" rules = {[{ required: true } ] } >
< Input / >
< / Form.Item >
< Form.Item name = "age" label = "User Age" rules = {[{ required: true } ] } >
< InputNumber / >
< / Form.Item >
< / Form >
< / Modal >
);
};
2022-05-19 09:46:26 +08:00
const App: React.FC = () => {
2022-08-23 16:55:57 +08:00
const [open, setOpen] = useState(false);
2019-07-03 20:14:39 +08:00
const showUserModal = () => {
2022-08-23 16:55:57 +08:00
setOpen(true);
2019-07-03 20:14:39 +08:00
};
const hideUserModal = () => {
2022-08-23 16:55:57 +08:00
setOpen(false);
2019-07-03 20:14:39 +08:00
};
2020-12-17 15:09:18 +08:00
const onFinish = (values: any) => {
2019-07-03 20:14:39 +08:00
console.log('Finish:', values);
};
return (
2021-11-26 12:18:21 +08:00
< Form.Provider
onFormFinish={(name, { values, forms }) => {
if (name === 'userForm') {
const { basicForm } = forms;
const users = basicForm.getFieldValue('users') || [];
basicForm.setFieldsValue({ users: [...users, values] });
2022-08-23 16:55:57 +08:00
setOpen(false);
2021-11-26 12:18:21 +08:00
}
}}
>
< Form { . . . layout } name = "basicForm" onFinish = {onFinish} >
< Form.Item name = "group" label = "Group Name" rules = {[{ required: true } ] } >
< Input / >
< / Form.Item >
< Form.Item
label="User List"
shouldUpdate={(prevValues, curValues) => prevValues.users !== curValues.users}
>
{({ getFieldValue }) => {
const users: UserType[] = getFieldValue('users') || [];
return users.length ? (
< ul >
{users.map((user, index) => (
< li key = {index} className = "user" >
< Avatar icon = {<UserOutlined / > } />
{user.name} - {user.age}
< / li >
))}
< / ul >
) : (
< Typography.Text className = "ant-form-text" type = "secondary" >
( < SmileOutlined / > No user yet. )
< / Typography.Text >
);
}}
< / Form.Item >
< Form.Item { . . . tailLayout } >
< Button htmlType = "submit" type = "primary" >
Submit
< / Button >
< Button htmlType = "button" style = {{ margin: ' 0 8px ' } } onClick = {showUserModal} >
Add User
< / Button >
< / Form.Item >
< / Form >
2022-08-23 16:55:57 +08:00
< ModalForm open = {open} onCancel = {hideUserModal} / >
2021-11-26 12:18:21 +08:00
< / Form.Provider >
2019-07-03 20:14:39 +08:00
);
};
2022-05-19 09:46:26 +08:00
export default App;
2019-07-03 20:14:39 +08:00
```
```css
#components-form-demo-form-context .user {
margin-bottom: 8px;
}
#components-form-demo-form-context .user .ant-avatar {
margin-right: 8px;
}
2020-06-28 16:03:56 +08:00
.ant-row-rtl #components -form-demo-form-context .user .ant-avatar {
margin-right: 0;
margin-left: 8px;
}
2019-07-03 20:14:39 +08:00
```