Antd 4.19 Modal + Form;打开modal时使用setFieldsValue,首次回显正常,第二次无效?
版本
react:16.14
antd:4.20.2
业务场景
Modal组件里面有一个Form,打开弹窗的时候,通过setFiledsValue来为表单设置回显数据。(modal 的 destroyOnClose为true)
DEMO
export default () => { const [form] = Form.useForm(); const [visible, setVisible] = React.useState<boolean>(); const open = () => { setVisible(true); form.setFieldsValue({ name: '哦哈约他大姨妈si', }) } const close = () => { setVisible(false); } return ( <> <Button onClick={open}>打开</Button> <Button onClick={close}>关闭</Button> <Modal destroyOnClose visible={visible} onCancel={close}> <Form layout="vertical" form={form}> <Form.Item label="hhh" name="name"><Input/></Form.Item> </Form> </Modal> </> ); };
问题现象
第一次打开弹窗编辑的时候,数据正常回显;第二次打开弹窗编辑时,数据无法正常回显,一直为空。
直接原因
1、Modal的destroyOnClose属性为true,使得在我们关闭弹窗的时候,Form组件被销毁;(具体原因下面会说)
2、react版本较旧
解决办法
1、destoryOnClose设置为false
2、react换到18.x可解决(可以自行去实验 )
根本原因
Q:为什么第一次正常?
A:上述操作其实是先给form的store设置值,然后在打开弹窗,因此再渲染form之前数据已经存在,所以能正常回显input里面的内容。
Q:为什么第二次不能正常回显?
A:关闭弹窗时Form组件被销毁,第二次打开会重新初始化,但是useForm方法的数据实例已经存在,里面记录了formItem上次的key,因此第二次setFIledsValue的时候,对于已经存在的记录,会强制从initValues里面拿数据赋值,因为在使用form的时候没有传initialValues,所以全部设置成了undefined,因此无法正常回显。
如下图:
每次Form销毁的时候会执行destoryForm,并设置prevWithoutPreserves
每次Form初始化的时候,都会执行setInitialValues,其中的prevWithoutPreserves就是对已有数据的纪录,这种就会从initialValues中拿数据。
ps:尽量使用initialValues来设置回显,更符合逻辑。根据实际业务场景来判断是否使用setFiledsValue