首页 > 解决方案 > React和Antd,表单数据在全屏抽屉失焦时破坏

问题描述

我试图在关闭时删除破坏,使用相同形式的钩子,不同形式的钩子,从钩子中删除,但没有任何效果。我已经控制台记录了显示模式和关闭模式的表单数据。显示模式具有表单数据,但在关闭模式的日志中数据被重置为undefined. 一旦模态打开,数据就会重置为null.

在以下代码中,您可以看到使用 AntDrawer 创建的全屏模式:

import React, { useEffect, useState } from "react";
import FullscreenDialog from "Components/FullScreenDialog";
import Form from "Components/Form";
import { Input, Typography, Button, Space, Menu, Dropdown } from "antd";
import { PlusCircleOutlined, CloseOutlined, DownOutlined } from "@ant-design/icons";
import HeaderInput from "Components/Inputs/HeaderInput";
import Table from "Components/Table";
import styled from "styled-components";
import { Services } from "Utilities/network";
import DetailsModal from "./DetailsModal";

const RootWrapper = styled.div`
  input::-webkit-outer-spin-button,
  input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  input[type="number"] {
    -moz-appearance: textfield;
  }
`;

const CreateVoucher = ({ visible, initalValue = {}, onSuccess = (e) => e, onClose = (e) => e }) => {
  const [form] = Form.useForm();
  const [voucherData, setVoucherData] = useState([]);
  const [newModal, setNewModal] = useState(false);
  const [formData, setFormData] = useState({});

  const handleSubmit = async () => {
    const { _id, name, header } = form.getFieldsValue(true);
    if (name && header && voucherData) {
      let resp = await Services.createVoucher({
        _id,
        name,
        header,
        voucherData,
      });
      if (resp.key) onSuccess();
    }
  };
  if (initalValue) {
    const { _id, name, header, voucherData } = initalValue;
    form.setFieldsValue({
      _id,
      name,
      header,
      voucherData,
    });
  }
  useEffect(() => {
    const { voucherData } = initalValue;
    if (voucherData && voucherData.length) setVoucherData(voucherData);
    else setVoucherData([]);
  }, [initalValue]);

  const handleDelete = (index) => {
    const tableData = voucherData.filter((data, dataIndex) => {
      if (index !== dataIndex) return data;
      return null;
    });
    setVoucherData(tableData);
  };

  return (
    <>
      <FullscreenDialog visible={visible} onClose={onClose}>
        <FullscreenDialog.Paper>
          <RootWrapper>
            <Typography.Text strong style={{ fontSize: "30px" }}>
              Generate Voucher
            </Typography.Text>
            <Form form={form}>
              <Space direction="vertical" style={{ width: "100%" }}>
                <Form.Item label="Voucher ID" name="name" rules={[{ required: true, message: "Please input ID" }]}>
                  <Input />
                </Form.Item>
                <HeaderInput
                  fieldProps={{
                    name: "header",
                    label: "Inoivce Header",
                    rules: [{ required: true, message: "Please select header" }],
                  }}
                  itemProps={{ placeholder: "Select Header for Voucher" }}
                />
                <Space style={{ float: "right", marginTop: "20px" }}>
                  <Button
                    type="primary"
                    shape="round"
                    icon={<PlusCircleOutlined />}
                    onClick={() => {
                      setFormData(form.getFieldsValue(true));
                      setNewModal(true);
                    }}
                  >
                    Add Details
                  </Button>
                </Space>

                <Table
                  dataSource={voucherData}
                  count={voucherData?.length || 0}
                  columns={[
                    {
                      title: "Label",
                      key: "label",
                      dataIndex: "label",
                      render: (_, record) => record.label,
                    },
                    {
                      title: "Details",
                      key: "detail",
                      dataIndex: "detail",
                      render: (_, record) => record.detail,
                    },
                    {
                      align: "right",
                      render: (_, record, index) => {
                        return (
                          <Dropdown
                            trigger={["click"]}
                            overlay={
                              <Menu>
                                <Menu.Item
                                  style={{ color: "red " }}
                                  onClick={() => {
                                    handleDelete(index);
                                  }}
                                >
                                  <CloseOutlined /> Delete
                                </Menu.Item>
                              </Menu>
                            }
                          >
                            <Button type="primary">
                              Edit
                              <DownOutlined />
                            </Button>
                          </Dropdown>
                        );
                      },
                    },
                  ]}
                />

                <Space style={{ float: "right", marginTop: "30px" }}>
                  <Button type="outline" onClick={onClose}>
                    Cancel
                  </Button>
                  <Button type="primary" htmlType="submit" onClick={handleSubmit}>
                    Submit
                  </Button>
                </Space>
              </Space>
            </Form>
          </RootWrapper>
        </FullscreenDialog.Paper>
      </FullscreenDialog>
      <DetailsModal
        visible={newModal}
        onClose={() => {
          setNewModal(false);
          console.log(formData);
          form.setFieldsValue({ name: "2222" });
          console.log(form.getFieldsValue(true));
        }}
        onSuccess={(data) => {
          setVoucherData([...voucherData, data]);
          setNewModal(false);
          form.setFieldsValue(formData);
        }}
      />
    </>
  );
};

export default CreateVoucher;

下面是 modal 使用另一种形式的代码:

import React from "react";
import { Modal, Space, Input, Button } from "antd";
import Form from "Components/Form";
import styled from "styled-components";

const RootWrapper = styled.div`
  input::-webkit-outer-spin-button,
  input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  input[type="number"] {
    -moz-appearance: textfield;
  }
`;

const DetailsModal = ({ visible, onClose = (e) => e, onSuccess = (e) => e }) => {
  const [form] = Form.useForm();

  return (
    <Modal
      visible={visible}
      destroyOnClose={true}
      onClose={() => {
        form.resetFields();
        onClose();
      }}
      onCancel={() => {
        form.resetFields();
        onClose(false);
      }}
      title="Add Details"
      footer={false}
    >
      <Form form={form}>
        <Space direction="vertical" style={{ width: "100%" }}>
          <RootWrapper>
            <Form.Item name="label" label="Label" rules={[{ required: true, message: "Please input label" }]}>
              <Input />
            </Form.Item>
            <Form.Item name="detail" label="Details" rules={[{ required: true, message: "Please input details" }]}>
              <Input />
            </Form.Item>
          </RootWrapper>
          <Space style={{ float: "right", marginTop: "20px" }}>
            <Button
              type="outline"
              onClick={() => {
                form.resetFields();
                onClose();
              }}
            >
              Cancel
            </Button>
            <Button
              type="primary"
              htmlType="submit"
              onClick={() => {
                const { detail, label } = form.getFieldsValue(true);
                onSuccess({ detail, label });
              }}
            >
              Submit
            </Button>
          </Space>
        </Space>
      </Form>
    </Modal>
  );
};

export default DetailsModal;

标签: reactjsantd

解决方案


推荐阅读