现象
Form 配合 Modal 使用时 destroyOnClose 会影响 useEffect 的执行,相应的 useEffect 中的一些操作如 resetFields 可能会不生效
resetFields 不生效演示
原因
有 destroyOnClose 先执行 useEffect,没有 destroyOnClose 后执行 useEffect
复现示例
demo代码
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Form, Input, Modal, Button } from 'antd';
const FormComponent = ({ form, record, onOk, type }) => {
console.log(`${type}_record2=`, record);
return (
<Form
form={form}
initialValues={record}
onFinish={(value) => {
onOk(value.data);
}}
>
<Form.Item name="data">
<Input />
</Form.Item>
<Form.Item>
<Button htmlType="submit">提交</Button>
</Form.Item>
</Form>
);
};
const App = () => {
const [visible, setVisible] = useState(false);
const [record, setRecord] = useState();
const [recordList, setRecordList] = useState([{ data: '111' }]);
const [form] = Form.useForm();
const { resetFields } = form;
useEffect(() => {
if (visible && record) {
console.log('app_record1=', record);
resetFields();
}
}, [visible, record, resetFields]);
return (
<div>
<Button
onClick={() => {
setRecord(recordList[0]);
setVisible(true);
}}
>
App 有 destroyOnClose 先执行 useEffect 导致其中的 resetFields 不生效
</Button>
<Modal
visible={visible}
onCancel={() => {
setVisible(false);
setRecord({ data: undefined });
}}
footer={null}
destroyOnClose
>
<FormComponent
form={form}
record={record}
type="app"
onOk={(data) => {
setRecord({ data: undefined });
setRecordList([{ data }]);
setVisible(false);
}}
/>
</Modal>
</div>
);
};
const Contain = () => {
const [visible, setVisible] = useState(false);
const [record, setRecord] = useState();
const [recordList, setRecordList] = useState([{ data: '111' }]);
const [form] = Form.useForm();
const { resetFields } = form;
useEffect(() => {
if (visible && record) {
console.log('contain_record1=', record);
resetFields();
}
}, [visible, record, resetFields]);
return (
<div>
<Button
onClick={() => {
setRecord(recordList[0]);
setVisible(true);
}}
>
Contain 无 destroyOnClose 后执行 useEffect 所以其中的 resetFields 生效
</Button>
<Modal
visible={visible}
type="contain"
onCancel={() => {
setVisible(false);
setRecord({ data: undefined });
}}
footer={null}
>
<FormComponent
form={form}
record={record}
type="contain"
onOk={(data) => {
setRecord({ data: undefined });
setRecordList([{ data }]);
setVisible(false);
}}
/>
</Modal>
</div>
);
};
ReactDOM.render(
<div>
<Contain />
<App />
</div>,
document.getElementById('container')
);