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