antd react组件库如何在模态对话中提交表单组件
How to submit form component in modal dialogue using antd react component library
在我组件的渲染方法中,我将 antd Modal 组件作为父组件,将 antd Form 组件作为子组件:
render() {
const myForm = Form.create()(AddNewItemForm);
...
return (
...
<Modal
title="Create new item"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
wrapClassName="vertical-center-modal"
okText="Save new item"
width="600"
>
<myForm />
</Modal>
...
如何通过单击模式保存按钮来提交我的表单?
我的解决方案是将模态对话和表单组件包装在一个新的包装器父组件中,在其中我在 handleCreate 方法中验证子表单组件。我已经使用 ref 属性来引用 FormOnModalWrapper 组件内的 myForm 子组件。我通过 props 从包装器父组件传递父处理程序到 myForm 组件实例。
class FormOnModalWrapper extends React.Component {
...
constructor(props) {
this.state =
{
visible: false
....
}
...
showModal = () => {
this.setState({
visible: true,
});
}
handleCreate = () => {
const form = this.form;
form.validateFields((err, values) => {
if (err) {
return;
}
console.log('Received values of form: ', values);
form.resetFields();
this.setState({ visible: false });
});
}
saveFormRef = (form) => {
this.form = form;
}
render() {
...
const myForm= Form.create()(CrateNewItemFormOnModal);
...
return (
<div>
<Button onClick={this.showModal}>Add</Button>
<myForm
visible={this.state.visible}
onCancel={this.handleCancel}
onCreate={this.handleCreate}
ref={this.saveFormRef}
/>
</div>
);
}
在 CrateNewItemFormOnModal 组件中 class 我有一个模态对话组件作为父组件,表单组件作为子组件:
export default class AddNewItemForm extends React.Component {
render() {
...
const { visible, onCancel, onCreate, form } = this.props;
...
return (
<Modal
title="Create new item"
visible={visible}
onOk={onCreate}
onCancel={onCancel}
okText="Create"
>
<Form>
...
</Form>
</Modal>
);
}
可以学习官方例子:https://ant.design/components/form/#components-form-demo-form-in-modal
我的解决方案是禁用模式的页脚并创建我自己的提交按钮:
<Modal footer={null}>
<Form onSubmit={this.customSubmit}>
...
<FormItem>
<Button type="primary" htmlType="submit">Submit</Button>
</FormItem>
</Form>
</Modal>
无需使用此解决方案包装模态框。
有一个看起来更简洁的新解决方案:
<Form id="myForm">
...
<Modal
...
footer={[
<Button form="myForm" key="submit" htmlType="submit">
Submit
</Button>
]}
>
<CustomForm />
</Modal>
这是因为按钮的 form 属性。 Browser support
现在,react hooks 已经出来了,你也可以使用 hooks 来达到同样的目的。通过为模式创建包装器组件并在表单所在的位置使用该组件。
包装组件:
<Modal
visible={state}
centered={true}
onCancel={() => setState(false)}
title={title}
destroyOnClose={true}
footer={footer}>
{children}
</Modal>
表单组件:
<WrapperModal
state={modalState}
setState={setModal}
title='Example Form'
footer={[
<button onClick={handleSubmit}>
SUBMIT
<button/>
]}>
<Form>
<Form.Item label='name '>
{getFieldDecorator('name ', {
rules: [
{
required: true,
message: 'please enter proper name'
}
]
})(<Input placeholder='name'/>)}
</Form.Item>
</Form>
</WrapperModal>
我在这里创建了一个包装器模态组件,它具有所有必要的模态api,我还为我的模态创建了一个自定义按钮
我的解决方案第一个解决方案
...
handleOk = (e) => {
e.preventDefault();
this.form.validateFields((err, values) => {
//do your submit process here
});
}
//set ref form
formRef = (form) => {
this.form = form;
}
render() {
const myForm = Form.create()(AddNewItemForm);
...
return (
...
<Modal
title="Create new item"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
wrapClassName="vertical-center-modal"
okText="Save new item"
width="600"
>
<myForm
ref={this.formRef}
/>
</Modal>
...
或者您可以使用此解决方案
...
handleOk = (e) => {
e.preventDefault();
this.form.validateFields((err, values) => {
//do your submit process here
});
}
render() {
const myForm = Form.create()(AddNewItemForm);
...
return (
...
<Modal
title="Create new item"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
wrapClassName="vertical-center-modal"
okText="Save new item"
width="600"
>
<myForm
wrappedComponentRef={(form) => this.formRef = form}
/>
</Modal>
...
想法是设置 ref 以包装表单组件。
请参阅下面的参考资料。
我的解决方案是使用钩子
import { Button, Modal, Form } from 'antd';
export default function ModalWithFormExample() {
const [visible, setVisible] = useState(false);
const [form] = Form.useForm();
const showModal = () => {
setVisible(true)
}
const handleSubmit = (values) => {
console.log(values)
}
const handleCancel = () => {
setVisible(false)
form.resetFields()
};
return (
<>
<Button onClick={showModal}>Open Modal</Button>
<Modal visible={visible} onOk={form.submit} onCancel={handleCancel}>
<Form form={form} onFinish={handleSubmit}>
{/* Any input */}
</Form>
</Modal>
</>
)
}
在 2021 年做到这一点的简单方法是 customized footer for modal
import { useState } from 'react'
import { Modal, Button, Form, Input } from 'antd'
export default function BasicModal() {
const [form] = Form.useForm()
const [isModalVisible, setIsModalVisible] = useState(false)
const showModal = () => setIsModalVisible(true)
const handleCancel = () => {
setIsModalVisible(false)
form.resetFields()
}
const handleOk = () => {
form.submit()
}
const onFinish = () => {
console.log('Form submited!')
setIsModalVisible(false)
}
return (
<>
<Button type="primary" onClick={showModal}>
Show Modal
</Button>
<Modal
title="Basic Modal"
visible={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
footer={[
<Button key="back" onClick={handleCancel}>
Cancel
</Button>,
<Button key="submit" type="primary" onClick={handleOk}>
Submit
</Button>,
]}
>
<Form labelCol={{ xs: { span: 6 } }} wrapperCol={{ xs: { span: 12 } }} form={form} onFinish={onFinish} scrollToFirstError>
<Form.Item name="input1" label="Input 1" rules={[{ required: true, message: "This field is required." }]}>
<Input />
</Form.Item>
<Form.Item name="input2" label="Input 2" rules={[{ required: true, message: "This field is required." }]}>
<Input />
</Form.Item>
</Form>
</Modal>
</>
)
}
在我组件的渲染方法中,我将 antd Modal 组件作为父组件,将 antd Form 组件作为子组件:
render() {
const myForm = Form.create()(AddNewItemForm);
...
return (
...
<Modal
title="Create new item"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
wrapClassName="vertical-center-modal"
okText="Save new item"
width="600"
>
<myForm />
</Modal>
...
如何通过单击模式保存按钮来提交我的表单?
我的解决方案是将模态对话和表单组件包装在一个新的包装器父组件中,在其中我在 handleCreate 方法中验证子表单组件。我已经使用 ref 属性来引用 FormOnModalWrapper 组件内的 myForm 子组件。我通过 props 从包装器父组件传递父处理程序到 myForm 组件实例。
class FormOnModalWrapper extends React.Component {
...
constructor(props) {
this.state =
{
visible: false
....
}
...
showModal = () => {
this.setState({
visible: true,
});
}
handleCreate = () => {
const form = this.form;
form.validateFields((err, values) => {
if (err) {
return;
}
console.log('Received values of form: ', values);
form.resetFields();
this.setState({ visible: false });
});
}
saveFormRef = (form) => {
this.form = form;
}
render() {
...
const myForm= Form.create()(CrateNewItemFormOnModal);
...
return (
<div>
<Button onClick={this.showModal}>Add</Button>
<myForm
visible={this.state.visible}
onCancel={this.handleCancel}
onCreate={this.handleCreate}
ref={this.saveFormRef}
/>
</div>
);
}
在 CrateNewItemFormOnModal 组件中 class 我有一个模态对话组件作为父组件,表单组件作为子组件:
export default class AddNewItemForm extends React.Component {
render() {
...
const { visible, onCancel, onCreate, form } = this.props;
...
return (
<Modal
title="Create new item"
visible={visible}
onOk={onCreate}
onCancel={onCancel}
okText="Create"
>
<Form>
...
</Form>
</Modal>
);
}
可以学习官方例子:https://ant.design/components/form/#components-form-demo-form-in-modal
我的解决方案是禁用模式的页脚并创建我自己的提交按钮:
<Modal footer={null}>
<Form onSubmit={this.customSubmit}>
...
<FormItem>
<Button type="primary" htmlType="submit">Submit</Button>
</FormItem>
</Form>
</Modal>
无需使用此解决方案包装模态框。
有一个看起来更简洁的新解决方案:
<Form id="myForm">
...
<Modal
...
footer={[
<Button form="myForm" key="submit" htmlType="submit">
Submit
</Button>
]}
>
<CustomForm />
</Modal>
这是因为按钮的 form 属性。 Browser support
现在,react hooks 已经出来了,你也可以使用 hooks 来达到同样的目的。通过为模式创建包装器组件并在表单所在的位置使用该组件。
包装组件:
<Modal
visible={state}
centered={true}
onCancel={() => setState(false)}
title={title}
destroyOnClose={true}
footer={footer}>
{children}
</Modal>
表单组件:
<WrapperModal
state={modalState}
setState={setModal}
title='Example Form'
footer={[
<button onClick={handleSubmit}>
SUBMIT
<button/>
]}>
<Form>
<Form.Item label='name '>
{getFieldDecorator('name ', {
rules: [
{
required: true,
message: 'please enter proper name'
}
]
})(<Input placeholder='name'/>)}
</Form.Item>
</Form>
</WrapperModal>
我在这里创建了一个包装器模态组件,它具有所有必要的模态api,我还为我的模态创建了一个自定义按钮
我的解决方案第一个解决方案
...
handleOk = (e) => {
e.preventDefault();
this.form.validateFields((err, values) => {
//do your submit process here
});
}
//set ref form
formRef = (form) => {
this.form = form;
}
render() {
const myForm = Form.create()(AddNewItemForm);
...
return (
...
<Modal
title="Create new item"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
wrapClassName="vertical-center-modal"
okText="Save new item"
width="600"
>
<myForm
ref={this.formRef}
/>
</Modal>
...
或者您可以使用此解决方案
...
handleOk = (e) => {
e.preventDefault();
this.form.validateFields((err, values) => {
//do your submit process here
});
}
render() {
const myForm = Form.create()(AddNewItemForm);
...
return (
...
<Modal
title="Create new item"
visible={this.state.visible}
onOk={this.handleOk}
onCancel={this.handleCancel}
wrapClassName="vertical-center-modal"
okText="Save new item"
width="600"
>
<myForm
wrappedComponentRef={(form) => this.formRef = form}
/>
</Modal>
...
想法是设置 ref 以包装表单组件。
请参阅下面的参考资料。
我的解决方案是使用钩子
import { Button, Modal, Form } from 'antd';
export default function ModalWithFormExample() {
const [visible, setVisible] = useState(false);
const [form] = Form.useForm();
const showModal = () => {
setVisible(true)
}
const handleSubmit = (values) => {
console.log(values)
}
const handleCancel = () => {
setVisible(false)
form.resetFields()
};
return (
<>
<Button onClick={showModal}>Open Modal</Button>
<Modal visible={visible} onOk={form.submit} onCancel={handleCancel}>
<Form form={form} onFinish={handleSubmit}>
{/* Any input */}
</Form>
</Modal>
</>
)
}
在 2021 年做到这一点的简单方法是 customized footer for modal
import { useState } from 'react'
import { Modal, Button, Form, Input } from 'antd'
export default function BasicModal() {
const [form] = Form.useForm()
const [isModalVisible, setIsModalVisible] = useState(false)
const showModal = () => setIsModalVisible(true)
const handleCancel = () => {
setIsModalVisible(false)
form.resetFields()
}
const handleOk = () => {
form.submit()
}
const onFinish = () => {
console.log('Form submited!')
setIsModalVisible(false)
}
return (
<>
<Button type="primary" onClick={showModal}>
Show Modal
</Button>
<Modal
title="Basic Modal"
visible={isModalVisible}
onOk={handleOk}
onCancel={handleCancel}
footer={[
<Button key="back" onClick={handleCancel}>
Cancel
</Button>,
<Button key="submit" type="primary" onClick={handleOk}>
Submit
</Button>,
]}
>
<Form labelCol={{ xs: { span: 6 } }} wrapperCol={{ xs: { span: 12 } }} form={form} onFinish={onFinish} scrollToFirstError>
<Form.Item name="input1" label="Input 1" rules={[{ required: true, message: "This field is required." }]}>
<Input />
</Form.Item>
<Form.Item name="input2" label="Input 2" rules={[{ required: true, message: "This field is required." }]}>
<Input />
</Form.Item>
</Form>
</Modal>
</>
)
}