Javascript 如何在react中验证多步骤表单

Javascript 如何在react中验证多步骤表单,javascript,reactjs,react-hooks,react-hook-form,Javascript,Reactjs,React Hooks,React Hook Form,我有一个多步骤表单,我正在使用react制作,以使用react钩子表单进行验证 我已经实现了90%的目标,但我面临的一个问题是获取第二个表单数据,它是动态的 我正在做的是 在我的第一个表单中,我有两个字段,当这些字段被填充(验证)时,我将进入下一个表单 在我的下一个表单中,我有两个输入字段,在add按钮上,用户也可以添加多行字段,这些字段工作正常 问题 现在,当我以第二种形式创建新字段时,我想验证它们,但不知道如何才能做到这一点 我所做的 在我的主要组件中,我这样做是为了验证 const

我有一个多步骤表单,我正在使用react制作,以使用
react钩子表单
进行验证

我已经实现了90%的目标,但我面临的一个问题是获取第二个表单数据,它是动态的

我正在做的是

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

  • 现在,当我以第二种形式创建新字段时,我想验证它们,但不知道如何才能做到这一点
我所做的

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

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}
      />
    ),
  },
];

在这里,如果在表格2中添加两个数据,我需要如下所示的数据

    {
  "fname": "dsteve",
  "sname": "smith",
  "userInfo": [
    {
      "desig": "ddd",
      "dept": "deptee"
    },
    {
      "desig": "ddd",
      "dept": "deptee"
    }
  ]
}
我已经做了一切,但在这里,只有我被卡住了,我知道问题在哪里

而不是这个

fields: ["fname", "sname"],
我必须这样做

fields:[`userInfo[0].name, `userInfo[0].sname],
fields:[`userInfo[0].name`,`userInfo[1].name`, `userInfo[0].sname`,`userInfo[1].sname],
这个0-1我必须根据索引进行动态调整,我不知道我遗漏了什么

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

编辑/更新

如果我这样做

fields:[`userInfo[0].name, `userInfo[0].sname],
fields:[`userInfo[0].name`,`userInfo[1].name`, `userInfo[0].sname`,`userInfo[1].sname],
所以需要对两个字段进行验证,但这是手动完成的,若用户创建了更多字段,那个么应该动态地获取这些字段

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

我愿意使用任何新方法,但这应该使用
react hook form
并完全满足我的要求


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

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

  • 为这两种形式创建两个方案:
  • 第二种形式也应该创建类似的模式

  • 创建第一个表单并通过解析器应用验证程序
  • 对第二个表单执行相同的操作-useForm+验证解析器

  • 下一部分是使第二个表单成为动态的,所以一定要使用hookuseFieldArray

  • 现在,您可以创建操作*(按钮/链接)*并传递它们{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),
     })
    

    您可以创建一个包含2个空字符串的数组,其中第一个字符串表示名称的第一行,而 第二个代表main组件中您的inputHolder下的第一行的名称:

     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: names,
          component: (register, errors, defaultValues) => (
            <Form2
              register={register}
              errors={errors}
              defaultValues={defaultValues}
              inputHolder={inputHolder}
              addRow={addRow}
            />
    
    字段:名称,
    组件:(寄存器、错误、默认值)=>(
    
    你应该像这个问题一样添加整个组件,这样其他人可以更快地帮助你。@NearHuscarl嘿,在上面的链接中,你没有进行验证,我想这是我遇到的主要问题。我的问题是,没有足够的上下文让我开始调试你的代码。@NearHuscarl嘿,我通过添加
    code sandbox
    link请检查我刚开始玩这个。我想如果我闯入几个组件而不是一个组件,情况会变得更加明显。但我已经注意到的一个潜在问题是,一旦添加了一行,就无法删除它。嘿,你能在
    code Sandbs中向我展示工作代码吗ox
    以便我可以测试
     const addRow = () => {
        console.log(inputHolder.length);
        let item = {
          id: inputHolder.length + 1,
          fname: "",
          sname: ""
        };
        setinputHolder([...inputHolder, item]);
        setNames([...names, "", ""]);
       
      };
    
    fields: names,
          component: (register, errors, defaultValues) => (
            <Form2
              register={register}
              errors={errors}
              defaultValues={defaultValues}
              inputHolder={inputHolder}
              addRow={addRow}
            />