问题描述
我对 React 和 JS 还很陌生,我目前正在尝试创建一个组件来将 antd 表单与 modal 集成,以便我可以利用诸如“验证”之类的表单功能。
这是我的代码:
发布请求的函数:
import baseUrl from "./baseUrl";
export async function _postSchoolRollOutRequest(schoolRollOutRequestForm) {
try {
const response = await fetch(
`${baseUrl}/Feedbacks/request/schoolRollOutRequest`,{
method: "POST",headers: {
Accept: "application/json","Content-Type": "application/json",},body: JSON.stringify(schoolRollOutRequestForm),}
);
const data = await response.json();
console.log("Post school roll out form success!");
return data;
} catch (e) {
console.log("Post school roll out form Failed!",e);
}
}
表单与模态集成组件:
import React,{ useState } from "react";
import { Modal,Button,Form,Input,Radio } from "antd";
import { _postSchoolRollOutRequest } from "../../api/FeedbacksApi";
import "./PopUp.scss";
export default (props) => {
const FormItem = Form.Item;
const [visible,setVisible] = useState(false);
const showModal = () => {
setVisible(true);
};
const handleOk = (schoolRollOutRequestForm) => {
_postSchoolRollOutRequest(schoolRollOutRequestForm);
setVisible(false);
};
const handleCancel = () => {
setVisible(false);
};
return (
<>
<Button type="primary" onClick={showModal}>
Roll-out My School!
</Button>
<Modal
destroyOnClose={true}
visible={visible}
title="Roll-out Request"
onCancel={handleCancel}
footer={[
<Button
block
key="submit"
type="primary"
onClick={(FeedbackSubmission) =>
handleOk({
shoolName: FeedbackSubmission.shoolName,otherFeedback: FeedbackSubmission.otherFeedback,contact: FeedbackSubmission.contact,})
}
>
Roll-out My School!
</Button>,]}
width={400}
>
<div className={"modal-body center"}>
<Form layout="vertical">
<Form.Item
label="Schools Name"
name="schoolName"
rules={[{ required: true }]}
>
{<Input type="text" label="schoolName" placeholder="UT Austin" />}
</Form.Item>
<FormItem
label="Any other requirements/Feedback (optional)"
name="otherFeedback"
>
{<Input type="textarea" placeholder="abcd..." />}
</FormItem>
<FormItem label="How do we contact you? (optional)" name="contact">
{<Input type="text" placeholder="abcd@email.com" />}
</FormItem>
</Form>
</div>
</Modal>
</>
);
};
然而,我遇到了两个让我很困惑的问题:
-
我认为页脚处的按钮不会触发表单的 onFinish,因此表单的验证不起作用,我想知道我能否获得有关适合我的情况的最佳实践的任何线索?
-
我尝试为“handleOk”伪造一个 json,然后是“_postSchoolRollOutRequest”,但似乎我的后端收到了一个负载为空的请求,我是否也能获得有关此问题的任何见解?
解决方法
代码沙盒: https://codesandbox.io/s/antdesignmodalform-stackoverflow-3yv4h?file=/index.js:920-3529
首先提交按钮应该在表单标签内。如果它在表单标签之外,则需要使用表单属性来触发它。
在您的情况下,模态总是在表单之外,因此您必须将提交按钮与表单链接。
以下是使用 ANT 设计实现它的方法。
Action Handler Code(如果您使用的是 redux,请根据您的要求修改回调部分)
export async function _postSchoolRollOutRequest(
schoolRollOutRequestForm,callback
) {
const baseUrl = "http://testing.com";
console.log("form values",schoolRollOutRequestForm);
try {
const response = await fetch(
`${baseUrl}/feedbacks/request/schoolRollOutRequest`,{
method: "POST",headers: {
Accept: "application/json","Content-Type": "application/json"
},body: JSON.stringify(schoolRollOutRequestForm)
}
);
const data = await response.json();
console.log("Post school roll out form success!");
callback(response.status,data);
} catch (e) {
callback(e.status);
console.log("Post school roll out form failed!",e);
}
}
表单组件
const FormModal = () => {
const [form] = Form.useForm();
const [visible,setVisible] = useState(false);
const [postData,setPostData] = useState({
loading: false,error: false,data: []
});
const onSubmit = (values) => {
setPostData({ ...postData,loading: true,error: false });
_postSchoolRollOutRequest(values,(status,data) => {
if (status === 200) {
form.resetFields();
setPostData({ ...postData,loading: false,data: data });
} else {
setPostData({
...postData,error: true,data: "Post school roll out form failed!"
});
}
});
};
return (
<>
<Button
type="primary"
onClick={() => {
setVisible(true);
}}
>
click to open form
</Button>
<Modal
visible={visible}
title="Post data"
okText="Submit"
cancelText="Cancel"
onCancel={() => {
setVisible(false);
}}
footer={[
<Button key="cancel" onClick={() => setVisible(false)}>
Cancel
</Button>,<Button
key="submit"
type="primary"
loading={postData.loading}
onClick={() => {
form
.validateFields()
.then((values) => {
onSubmit(values);
})
.catch((info) => {
console.log("Validate Failed:",info);
});
}}
>
Submit
</Button>
]}
>
<Form
form={form}
layout="vertical"
name="form_in_modal"
initialValues={{
modifier: "public"
}}
>
<Form.Item
label="Schools Name"
name="schoolName"
rules={[
{
required: true,message: ""
}
]}
>
<Input />
</Form.Item>
<Form.Item
label="Any other requirements/feedback (optional)"
name="otherFeedback"
>
<Input type="textarea" />
</Form.Item>
<Form.Item label="How do we contact you? (optional)" name="contact">
<Input />
</Form.Item>
{postData.error && (
<>
<br />
<span style={{ color: "red" }}>{postData.data}</span>
</>
)}
</Form>
</Modal>
</>
);
};