自己封装了一个组件:CUDataModal
代码如下:
components/CUDataModal.tsx
import React, { useEffect } from 'react';
import { Modal, Form, Input, Button } from 'antd';
import { Rule } from 'antd/es/form';
import { useForm } from 'antd/es/form/Form';
// 删除 CSS 导入
// 删除 import './CUDataModal.css';
interface Field {
name: string;
label: string;
type: string;
rules?: unknown[];
}
interface CUDataModalProps {
open: boolean;
onClose: () => void;
onSubmit: (values: unknown) => void;
mode: 'create' | 'update';
fields: Field[];
initialValues?: unknown;
}
const CUDataModal: React.FC<CUDataModalProps> = ({ open, onClose, onSubmit, mode, fields, initialValues }) => {
const [form] = useForm();
useEffect(() => {
if (form) {
form.resetFields();
}
}, [form]);
useEffect(() => {
if (mode === 'update' && initialValues) {
form.setFieldsValue(initialValues);
} else {
form.resetFields();
}
}, [mode, initialValues, form]);
const handleOk = () => {
form
.validateFields()
.then(values => {
onSubmit(values);
onClose();
})
.catch(info => {
console.log('Validate Failed:', info);
});
};
return (
<Modal
open={open}
title={mode === 'create' ? 'Create Data' : 'Update Data'}
onCancel={onClose}
centered
// 删除 className 和 style 属性
footer={[
<Button key="back" onClick={onClose}>
Cancel
</Button>,
<Button key="submit" type="primary" onClick={handleOk}>
Confirm
</Button>,
]}
>
<Form form={form} layout="vertical">
{fields.map(field => (
<Form.Item
key={field.name}
name={field.name}
label={field.label}
rules={field.rules as Rule[]}
>
{field.type === 'text' && <Input />}
{/* 可以根据需要添加更多类型的输入框 */}
</Form.Item>
))}
</Form>
</Modal>
);
};
export default CUDataModal;
components/CUDataModal.css
.custom-modal {
display: flex;
align-items: center;
justify-content: center;
}
.custom-modal .ant-modal-content {
top: 0;
padding: 0;
}
调用执行:
App.tsx
import React, { useState } from 'react';
import { Button } from 'antd';
import CUDataModal from './components/CUDataModal';
const App: React.FC = () => {
const [ModalOpen, setModalOpen] = useState(false);
const [mode, setMode] = useState<'create' | 'update'>('create');
const [initialValues, setInitialValues] = useState<unknown>(null);
const fields = [
{ name: 'name', label: 'Name', type: 'text', rules: [{ required: true, message: 'Please input the name!' }] },
{ name: 'age', label: 'Age', type: 'text', rules: [{ required: true, message: 'Please input the age!' }] },
// 可以根据需要添加更多字段
];
const handleCreate = () => {
setMode('create');
setInitialValues(null);
setModalOpen(true);
};
const handleUpdate = () => {
setMode('update');
setInitialValues({ name: 'John Doe', age: 30 });
setModalOpen(true);
};
const handleSubmit = (values: unknown) => {
console.log('Submitted values:', values);
};
return (
<div>
<Button type="primary" onClick={handleCreate}>
Create Data
</Button>
<Button type="default" onClick={handleUpdate} style={{ marginLeft: 8 }}>
Update Data
</Button>
<CUDataModal
open={ModalOpen}
onClose={() => setModalOpen(false)}
onSubmit={handleSubmit}
mode={mode}
fields={fields}
initialValues={initialValues}
/>
</div>
);
};
export default App;
但是现在有1个问题:
想要点击时候,从中间弹出,但是这里是从左边弹出:
但是代码是定义了Modal的centered属性的,不知道为何还是这样弹出:
报错应该是未点击open的时候报错的吧,可能是初始化modal的时候就执行了第一个useEffect,但是这个时候modal没渲染,绑不到实例就报错了
或者试试modal的forceRender方法,官网FAQ链接