如何将 react-hook-form 用于嵌套数组

Posted

技术标签:

【中文标题】如何将 react-hook-form 用于嵌套数组【英文标题】:How to use react-hook-form for nested array 【发布时间】:2021-04-28 22:14:43 【问题描述】:

我正在尝试使用反应钩子形式来创建嵌套数组。我已经用我的示例代码附加了一个沙盒

代码片段

<ul>
        fields.map((item, index) => 
          return (
            <li key=item.id>
              <label> single input </label>
              <input
                name=`test[$index].task`
                ref=register()
                defaultValue=item.task
              />
              <br />
              <label> first Name </label>
              <input
                name=`test[$index].name.first`
                ref=register()
                defaultValue=item.name.first
              />
              <br />
              <label>last Name </label>
              <input
                name=`test[$index].name.last`
                ref=register()
                defaultValue=item.name.last
              />
              <br />

              <label>First Nested </label>
              <input
                name=`test[$index].nestedArray[$index].firstNested`
                ref=register()
                // defaultValue=item.nestedArray.nested
              />

              <br />
              <label> Second Nested </label>
              <input
                name=`test[$index].nestedArray[$index].secondNested`
                ref=register()
                // defaultValue=item.nestedArray.nested
              />
              <br />

              <button type="button" onClick=() => remove(index)>
                Delete
              </button>
            </li>
          );
        )
      </ul>

问题

初始步骤工作正常。我能够在“nestedArray”中获取数据。但是当我附加多个嵌套数组时,我的数据。我的“nestedArray”总是以“null”开头,如果我追加更多,“null”会继续添加。我怎样才能避免这个“空”值?我不想保留以前的输入。我想完全避免空值。

样本输出


   "test":[
      
         "task":"single",
         "name":
            "first":"Jack",
            "last":"Box"
         ,
         "nestedArray":[
            
               "firstNested":"firstNested",
               "secondNested":"firstSecondNested"
            
         ]
      ,
      
         "task":"Second",
         "name":
            "first":"Kate",
            "last":"Smith"
         ,
         "nestedArray":[
            **null,**
            
               "firstNested":"SecondNested",
               "secondNested":"SecondNestedSecond"
            
         ]
      
   ]

预期样本输出


   "test":[
      
         "task":"single",
         "name":
            "first":"Jack",
            "last":"Box"
         ,
         "nestedArray":[
            
               "firstNested":"firstNested",
               "secondNested":"firstSecondNested"
            
         ]
      ,
      
         "task":"Second",
         "name":
            "first":"Kate",
            "last":"Smith"
         ,
         "nestedArray":[
            
               "firstNested":"SecondNested",
               "secondNested":"SecondNestedSecond"
            
         ]
      
   ]

在沙盒中重现的步骤

    点击追加 提供详细信息 在控制台中查看数据 点击追加(再次)添加另一组数据 控制台将在嵌套数组中显示“null”。

参考文献

Code Sandbox

代码片段

<ul>
        fields.map((item, index) => 
          return (
            <li key=item.id>
              <label> single input </label>
              <input
                name=`test[$index].task`
                ref=register()
                defaultValue=item.task
              />
              <br />
              <label> first Name </label>
              <input
                name=`test[$index].name.first`
                ref=register()
                defaultValue=item.name.first
              />
              <br />
              <label>last Name </label>
              <input
                name=`test[$index].name.last`
                ref=register()
                defaultValue=item.name.last
              />
              <br />

              <label>First Nested </label>
              <input
                name=`test[$index].nestedArray[$index].firstNested`
                ref=register()
                // defaultValue=item.nestedArray.nested
              />

              <br />
              <label> Second Nested </label>
              <input
                name=`test[$index].nestedArray[$index].secondNested`
                ref=register()
                // defaultValue=item.nestedArray.nested
              />
              <br />

              <button type="button" onClick=() => remove(index)>
                Delete
              </button>
            </li>
          );
        )
      </ul>

【问题讨论】:

【参考方案1】:

让我知道这是否有效。也许您不需要索引嵌套数组,因为它已被映射。它在我没有空值的情况下在控制台中工作。我认为既然您已经将“测试”作为目标:

`test[$index].nestedArray.firstNested`

您可能也不需要为 nestedArray 编制索引?

      <ul>
        fields.map((item, index) => 
          return (
            <li key=item.id>
              <label> single input </label>
              <input
                name=`test[$index].task`
                ref=register()
                defaultValue=item.task
              />
              <br />
              <label> first Name </label>
              <input
                name=`test[$index].name.first`
                ref=register()
                defaultValue=item.name.first
              />
              <br />
              <label>last Name </label>
              <input
                name=`test[$index].name.last`
                ref=register()
                defaultValue=item.name.last
              />
              <br />

              <label>First Nested </label>
              <input
                name=`test[$index].nestedArray.firstNested` //removed index
                ref=register()
                // defaultValue=item.nestedArray.nested
              />

              <br />
              <label> Second Nested </label>
              <input
                name=`test[$index].nestedArray.secondNested` //removed index
                ref=register()
                // defaultValue=item.nestedArray.nested
              />
              <br />

              <button type="button" onClick=() => remove(index)>
                Delete
              </button>
            </li>
          );
        )
      </ul>

【讨论】:

我想我可以在这里工作:codesandbox.io/s/… 欣赏!这个简单的失误让我困了好几个小时! @Jesse 我真的很幸运,我什至没有真正看你的代码哈哈 实际上这对我不起作用。我需要第二个 $[index] 来将它变成一个数组。没有它,json 就没有方括号。【参考方案2】:

这个怎么样,这行得通吗,它保留了数组括号并且没有空值。

也许由于地图索引增加,nestedArray 过滤当前地图索引中的值,但由于它还没有进入下一个索引,它会为该迭代创建一个空值。

代码:https://codesandbox.io/s/react-hook-form-usefieldarray-nested-arrays-forked-9sxrt?file=/src/fieldArray.js:302-1778

      <ul>
        fields.map((item, index) => 
          return (
            <li key=item.id>
              <label> single input </label>
              <input
                name=`test[$index].task`
                ref=register()
                defaultValue=item.task
              />
              <br />
              <label> first Name </label>
              <input
                name=`test[$index].name.first`
                ref=register()
                defaultValue=item.name.first
              />
              <br />
              <label>last Name </label>
              <input
                name=`test[$index].name.last`
                ref=register()
                defaultValue=item.name.last
              />
              <br />

              <label>First Nested </label>
              <input
                name=`test[$index].nestedArray[0].firstNested` //changed index to 0
                ref=register()
                // defaultValue=item.nestedArray.nested
              />

              <br />
              <label> Second Nested </label>
              <input
                name=`test[$index].nestedArray[0].secondNested` //changed index to 0
                ref=register()
                // defaultValue=item.nestedArray.nested
              />
              <br />

              <button type="button" onClick=() => remove(index)>
                Delete
              </button>
            </li>
          );
        )
      </ul>

【讨论】:

以上是关于如何将 react-hook-form 用于嵌套数组的主要内容,如果未能解决你的问题,请参考以下文章

MUI 自动完成功能不适用于 react-hook-form

如何使用 react-hook-form 有条件地禁用提交按钮?

如何使用 useEffect() 更改 React-Hook-Form defaultValue?

React-hook-form Demo之外——实际的用法

如何使用 React-Hook-Form 设置焦点

在 react-hook-form 中设置 DatePicker 的值(来自 antd)