将 Ant Design Form 与 Modal 集成

问题描述

我对 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>
    </>
  );
};

然而,我遇到了两个让我很困惑的问题:

  1. 我认为页脚处的按钮不会触发表单的 onFinish,因此表单的验证不起作用,我想知道我能否获得有关适合我的情况的最佳实践的任何线索?

  2. 我尝试为“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>
    </>
  );
};