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

 

 

posted @ 2022-05-07 15:59  蒋大忙  阅读(2553)  评论(0编辑  收藏  举报