1. 本际云推荐 - 专业推荐VPS、服务器,IDC点评首页
  2. 云主机运维
  3. VPS运维

antd-Form4.x一个页面中多个表单处理

前言

我是本际云服务器推荐网的小编小本本,今天在开发中发现一个页面的表单其实是两个部分,其中一部分还在另一个页面引用了,导致代码量增加。所以我决定进行优化,为了重复使用这里的表单。

antd-Form4.x一个页面中多个表单处理

如图,需求就是将下面两个表单拆开,可以重复使用,实际两部分可能有很多表单,这里方便起见,只写了三个。

涉及到知识点

1. React Hooks

2. Antd 4.0(Form)

3. Promise

4. 子父组件传值和父组件调用子组件方法

实现方法

具体实现我放在了 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> 
  ); 
}></import>

在该文件中,我们引入了两个表单的模版,通过 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.benjiyun.com/yunzhujiyunwei/vps-yunwei/7403.html