如何在反应中验证多步表单

Posted

技术标签:

【中文标题】如何在反应中验证多步表单【英文标题】:How to validate multistep form in react 【发布时间】:2021-01-22 05:43:11 【问题描述】:

我有一个多步骤表单,我正在使用 react 进行验证,我正在使用 react-hook-form

我已经完成了 90% 的事情,但我面临的问题之一是获取动态的第二个表单数据。

我正在做的是

在我的第一个表单中,当填写(验证)两个字段时,我将进入下一个表单 在我的下一个表单中,我有两个输入字段,在添加按钮上,用户也可以添加多行字段,这些都可以正常工作

问题

现在,当我在第二种表单中创建新字段时,我想验证它们,但不知道该怎么做。

我做了什么

在我的主要组件中,我这样做是为了验证

const forms = [
  
    fields: ['desig', 'dept'],
    component: () => (
      <Pro register=register errors=errors defaultValues=defaultValues />
    ),
  ,
  
    fields: [
      `userInfo[0].fname`, // here I am facing issue if I am statically putting 0,1 then it is validating that perticular form
      `userInfo[0].sirname`,
    ],
    component: () => (
      <Basic
        register=register
        errors=errors
        defaultValues=defaultValues
        inputHolder=inputHolder
        deleteRow=deleteRow
        addRow=addRow
      />
    ),
  ,
];

点击提交,我正在这样做

const handleSubmit = (e) => 
  triggerValidation(forms[currentForm].fields).then((valid) => 
    if (valid) 
      console.log('whole form data - ', JSON.stringify(defaultValues));
    
  );
;

如果在form2中添加两个数据,我想要如下数据

    
  "fname": "dsteve",
  "sname": "smith",
  "userInfo": [
    
      "desig": "ddd",
      "dept": "deptee"
    ,
    
      "desig": "ddd",
      "dept": "deptee"
    
  ]

我已经做了所有事情,但这里只有我被卡住了,我知道问题出在哪里

不是这个

fields: ["fname", "sname"],

我必须这样做

fields:[`userInfo[0].name, `userInfo[0].sname],

这个0-1我要根据索引动态,我不知道我错过了什么

我尝试通过inputHolder映射带有索引的字段,但没有成功

编辑/更新

如果我这样做

fields:[`userInfo[0].name`,`userInfo[1].name`, `userInfo[0].sname`,`userInfo[1].sname],

所以它对两个字段进行验证,但这是我手动操作的,如果用户创建更多字段,那么应该动态地获取这些字段。

这是我的代码沙箱,其中包含完整代码

Here is my code sandbox

我愿意使用任何新方法,但应该使用 react-hook-form 并完全填写我正在尝试做的事情

我现在不知道如何推进我的方法

【问题讨论】:

您应该像这个问题here 一样添加整个组件,以便其他人可以更快地帮助您。 @NearHuscarl 嘿,在上面的链接中,您没有进行验证,我认为这是我被卡住的要点。 我的意思是,没有足够的上下文让我开始调试您的代码。 @NearHuscarl 嘿,我已经通过添加 code sandbox 链接编辑了我的帖子,请检查 我刚开始玩这个。我认为如果我分解成几个组件而不是一个组件,将会变得更加明显。但是我已经注意到的一个潜在问题是,一旦添加了一行,就无法删除它。 【参考方案1】:

您可以创建一个包含 2 个空字符串的数组,其中第一个表示第一行 F 名称,并且 第二个代表MainComponent中你的inputHolder下的第一行S名称:

 const [inputHolder, setinputHolder] = useState([
    
      id: 1,
      fname: "",
      sname: ""
    
  ]);
  const [names, setNames] = useState(["", ""]);

接下来,每次用户向名称数组中的空字符串添加新行时。

 const addRow = () => 
    console.log(inputHolder.length);
    let item = 
      id: inputHolder.length + 1,
      fname: "",
      sname: ""
    ;
    setinputHolder([...inputHolder, item]);
    setNames([...names, "", ""]);
   
  ;

其中每个空字符串代表 F 名称和 S 名称。 最后,fields 设置为第二种形式的名称:

fields: names,
      component: (register, errors, defaultValues) => (
        <Form2
          register=register
          errors=errors
          defaultValues=defaultValues
          inputHolder=inputHolder
          addRow=addRow
        />

【讨论】:

嘿,你能告诉我code sandbox中的工作代码,以便我可以测试【参考方案2】:

我建议您使用 yup 作为验证工具。这是一个强大的工具。

    为这两种表单创建两个方案:
 import * as yup rom 'yup';
    
 const schema = yup.object().shape(
   field1: yup.string().required() // number, array - whatever,
   field2: yup.string().required(),
 )

也应该为第二种形式创建类似的模式

    创建第一个表单并通过解析器应用您的验证器
import  yupResolver  from '@hookform/resolvers/yup';

const  register, handleSubmit  = useForm(
  resolver: yupResolver(schema),
);

    对第二个表单执行相同操作 - useForm + 验证 resolver

    下一部分是让你的第二个表单是动态的,所以一定要使用钩子 useFieldArray

const  fields, append, remove  = useFieldArray(
  name: 'userInfo', *// key, a part of path to access your fields - userInfo[n].fname*
  control: form.control, *// to connect you fields to basic form* 
);

    现在您可以创建操作*(按钮/链接)* 并将它们传递给 append, remove 操作。

    fields 应默认由 .map 呈现。一旦您尝试使用 (n) 计数部分验证您的第二个表单 - 您的架构将应用于每个部分。

还有另一种解决方案,您可以使用第二种形式跳过部分(如果您的第二种架构可能很大,我更喜欢这种方式)。

您可以将您的 useFieldArray 字段连接到第一个表单,您的单一验证架构如下所示:

 import * as yup rom 'yup';
    
 const infoSchema = yup.object().schema(
   firstName: yup.string(),
   lastName: yup.string(),
 )

 *// enhance infoSchema to your expected logic.* 

 const schema = yup.object().shape(
   field1: yup.string().required() // number, array - whatever,
   field2: yup.string().required(),
   userInfo: yup.array().of(infoSchema),
 )

【讨论】:

以上是关于如何在反应中验证多步表单的主要内容,如果未能解决你的问题,请参考以下文章

反应采取错误验证的多步骤形式

Parsley 多步表单 - 单击下一步验证

在进行后突变之前反应如何验证表单

如何实现一个简单的反应多步控制

如何使用验证编辑嵌套的反应式表单?

如何使用反应表单挂钩验证反应日期选择器