今天开发的时候,发现一个页面的表单其实是两个部分,其中一部分还在另一个页面引用了。这就增加代码量,所以优化下,为了重复使用这里的表单。
如图,需求就是将下面两个表单拆开,可以重复使用,实际两部分可能有很多表单,这里方便起见,只写了三个。
react hooks
antd 4.0(Form)
Promise
子父组件传值和父组件调用子组件方法
具体实现:我放在了Codesandbox,可以直接打开调试
1、首先为了充分复用表单组件,那么就要拆分的彻底一点,不能关联太多内容。
2、一个模版表单多带带作为一个组件,表单通过useForm()创建。
3、在组件外部进行表单提交,分别触发,然后通过Promise.all方法获取表单数据。
4、编辑的时候,可以通过props将给表单赋值,然后给子组件注册供父组件调用的方法。
我们通过codesandbox
来试验下,这里表单添加的比较少,可以自行增加。
新建index.js
文件,表单最后显示在这里
两个表单模版:templateForm1.js
templateForm2.js
,由于这两个文件的内容基本一样,需要根据自己的表单内容定义,所以我们这里写了一个。
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">内部信息</Divider> <TemplateForm1 ref={template1Ref} formItemLayout={formItemLayout} /> <Divider orientation="left">外部信息</Divider> <TemplateForm2 ref={template2Ref} formItemLayout={formItemLayout} /> <Button onClick={handleCommit}>提交</Button> </div> ); } 复制代码
在该文件中,我们引入了两个表单的模版,通过ref属性获取组件,通过props传入父组件的变量。
当我们调用handleCommit
的时候,该函数会调用子组件定义好的commitForm
的方法来获取表单的数据,获取的数据通过回调函数返回。
因为多个组件存在异步获取的问题,所以这里通过promise.all
方法,获取多个表单的内容,然后统一处理。
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: "请输入名称" }]} > <Input placeholder="点输入名称" /> </Form.Item> </Form> ); }; export default forwardRef(TemplateForm1); 复制代码
这个组件是我们定义的表单模版,正常读取后,通过async
和await
获取表单内容,最后再通过commitForm
方法,返回给父组件。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/127958.html
摘要:解决方案可以解决在手机上点击事件的延迟的模块,事件也是为了解决在的延迟问题显示屏原理及设计方案说明屏是一种具备超高像素密度的液晶屏,同样大小的屏幕上显示的像素点由个变为多个,如在同样带下的屏幕上,苹果设备的显示屏中,像素点个变为个。 Meta基础知识: H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 //一、HTML页面结构 // width 设置viewport宽度,为一...
摘要:解决方案可以解决在手机上点击事件的延迟的模块,事件也是为了解决在的延迟问题显示屏原理及设计方案说明屏是一种具备超高像素密度的液晶屏,同样大小的屏幕上显示的像素点由个变为多个,如在同样带下的屏幕上,苹果设备的显示屏中,像素点个变为个。 Meta基础知识: H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 //一、HTML页面结构 // width 设置viewport宽度,为一...
摘要:解决方案可以解决在手机上点击事件的延迟的模块,事件也是为了解决在的延迟问题显示屏原理及设计方案说明屏是一种具备超高像素密度的液晶屏,同样大小的屏幕上显示的像素点由个变为多个,如在同样带下的屏幕上,苹果设备的显示屏中,像素点个变为个。 Meta基础知识: H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 //一、HTML页面结构 // width 设置viewport宽度,为一...
阅读 115·2024-11-07 18:25
阅读 130164·2024-02-01 10:43
阅读 789·2024-01-31 14:58
阅读 764·2024-01-31 14:54
阅读 82582·2024-01-29 17:11
阅读 2890·2024-01-25 14:55
阅读 1928·2023-06-02 13:36
阅读 2870·2023-05-23 10:26