今天開發(fā)的時(shí)候,發(fā)現(xiàn)一個(gè)頁面的表單其實(shí)是兩個(gè)部分,其中一部分還在另一個(gè)頁面引用了。這就增加代碼量,所以優(yōu)化下,為了重復(fù)使用這里的表單。
如圖,需求就是將下面兩個(gè)表單拆開,可以重復(fù)使用,實(shí)際兩部分可能有很多表單,這里方便起見,只寫了三個(gè)。
react hooks
antd 4.0(Form)
Promise
子父組件傳值和父組件調(diào)用子組件方法
具體實(shí)現(xiàn):我放在了Codesandbox,可以直接打開調(diào)試
1、首先為了充分復(fù)用表單組件,那么就要拆分的徹底一點(diǎn),不能關(guān)聯(lián)太多內(nèi)容。
2、一個(gè)模版表單多帶帶作為一個(gè)組件,表單通過useForm()創(chuàng)建。
3、在組件外部進(jìn)行表單提交,分別觸發(fā),然后通過Promise.all方法獲取表單數(shù)據(jù)。
4、編輯的時(shí)候,可以通過props將給表單賦值,然后給子組件注冊(cè)供父組件調(diào)用的方法。
我們通過codesandbox
來試驗(yàn)下,這里表單添加的比較少,可以自行增加。
新建index.js
文件,表單最后顯示在這里
兩個(gè)表單模版:templateForm1.js
templateForm2.js
,由于這兩個(gè)文件的內(nèi)容基本一樣,需要根據(jù)自己的表單內(nèi)容定義,所以我們這里寫了一個(gè)。
import React, { useRef } from "react"; import { Button, Divider } from "antd"; import TemplateForm1 from "./templateForm1"; import TemplateForm2 from "./templateForm2"; export default function App() { const template1Ref = useRef(); const template2Ref = useRef(); const formItemLayout = { labelCol: { span: 4 }, wrapperCol: { span: 10 } }; const handleCommit = () => { let template1Data = new Promise((resolve, reject) => { template1Ref.current.commitForm((value) => { resolve(value); }); }); let template2Data = new Promise((resolve, reject) => { template2Ref.current.commitForm((value) => { resolve(value); }); }); Promise.all([template1Data, template2Data]).then((res) => { console.log("get", res); }); }; return ( <div className="App"> <Divider orientation="left">內(nèi)部信息</Divider> <TemplateForm1 ref={template1Ref} formItemLayout={formItemLayout} /> <Divider orientation="left">外部信息</Divider> <TemplateForm2 ref={template2Ref} formItemLayout={formItemLayout} /> <Button onClick={handleCommit}>提交</Button> </div> ); } 復(fù)制代碼
在該文件中,我們引入了兩個(gè)表單的模版,通過ref屬性獲取組件,通過props傳入父組件的變量。
當(dāng)我們調(diào)用handleCommit
的時(shí)候,該函數(shù)會(huì)調(diào)用子組件定義好的commitForm
的方法來獲取表單的數(shù)據(jù),獲取的數(shù)據(jù)通過回調(diào)函數(shù)返回。
因?yàn)槎鄠€(gè)組件存在異步獲取的問題,所以這里通過promise.all
方法,獲取多個(gè)表單的內(nèi)容,然后統(tǒng)一處理。
import React, { useImperativeHandle, forwardRef } from "react"; import { Form, Input } from "antd"; const TemplateForm1 = (props, ref) => { const { formItemLayout } = props; const [form] = Form.useForm(); useImperativeHandle(ref, () => ({ commitForm: (cb) => { handleCommit(cb); } })); const handleCommit = async (cb) => { try { const values = await form.validateFields(); cb(values); } catch (err) { console.log(err); } }; return ( <Form form={form} {...formItemLayout}> <Form.Item name="Name" label="名稱" rules={[{ required: true, message: "請(qǐng)輸入名稱" }]} > <Input placeholder="點(diǎn)輸入名稱" /> </Form.Item> </Form> ); }; export default forwardRef(TemplateForm1); 復(fù)制代碼
這個(gè)組件是我們定義的表單模版,正常讀取后,通過async
和await
獲取表單內(nèi)容,最后再通過commitForm
方法,返回給父組件。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/127958.html
摘要:解決方案可以解決在手機(jī)上點(diǎn)擊事件的延遲的模塊,事件也是為了解決在的延遲問題顯示屏原理及設(shè)計(jì)方案說明屏是一種具備超高像素密度的液晶屏,同樣大小的屏幕上顯示的像素點(diǎn)由個(gè)變?yōu)槎鄠€(gè),如在同樣帶下的屏幕上,蘋果設(shè)備的顯示屏中,像素點(diǎn)個(gè)變?yōu)閭€(gè)。 Meta基礎(chǔ)知識(shí): H5頁面窗口自動(dòng)調(diào)整到設(shè)備寬度,并禁止用戶縮放頁面 //一、HTML頁面結(jié)構(gòu) // width 設(shè)置viewport寬度,為一...
摘要:解決方案可以解決在手機(jī)上點(diǎn)擊事件的延遲的模塊,事件也是為了解決在的延遲問題顯示屏原理及設(shè)計(jì)方案說明屏是一種具備超高像素密度的液晶屏,同樣大小的屏幕上顯示的像素點(diǎn)由個(gè)變?yōu)槎鄠€(gè),如在同樣帶下的屏幕上,蘋果設(shè)備的顯示屏中,像素點(diǎn)個(gè)變?yōu)閭€(gè)。 Meta基礎(chǔ)知識(shí): H5頁面窗口自動(dòng)調(diào)整到設(shè)備寬度,并禁止用戶縮放頁面 //一、HTML頁面結(jié)構(gòu) // width 設(shè)置viewport寬度,為一...
摘要:解決方案可以解決在手機(jī)上點(diǎn)擊事件的延遲的模塊,事件也是為了解決在的延遲問題顯示屏原理及設(shè)計(jì)方案說明屏是一種具備超高像素密度的液晶屏,同樣大小的屏幕上顯示的像素點(diǎn)由個(gè)變?yōu)槎鄠€(gè),如在同樣帶下的屏幕上,蘋果設(shè)備的顯示屏中,像素點(diǎn)個(gè)變?yōu)閭€(gè)。 Meta基礎(chǔ)知識(shí): H5頁面窗口自動(dòng)調(diào)整到設(shè)備寬度,并禁止用戶縮放頁面 //一、HTML頁面結(jié)構(gòu) // width 設(shè)置viewport寬度,為一...
閱讀 430·2024-11-07 18:25
閱讀 130684·2024-02-01 10:43
閱讀 923·2024-01-31 14:58
閱讀 893·2024-01-31 14:54
閱讀 82949·2024-01-29 17:11
閱讀 3225·2024-01-25 14:55
閱讀 2036·2023-06-02 13:36
閱讀 3133·2023-05-23 10:26