在 react-hook-form 的 useFieldArray 上异步调用 reset 时,reset 无法正常工作
Posted
技术标签:
【中文标题】在 react-hook-form 的 useFieldArray 上异步调用 reset 时,reset 无法正常工作【英文标题】:When reset is called asynchronously on react-hook-form's useFieldArray, reset doesn't work correctly 【发布时间】:2022-01-16 14:22:00 【问题描述】:我正在使用 react-hook-form 和 react-navigation。在我的用例中,我使用useFieldArray
来控制不断增长的输入数组,并且当用户按下HeaderBackButton
时我想reset
表单。但是,当我将reset
传递给HeaderBackButton
的onPress
属性并按下按钮时,只要字段数组有任何更改,都会出现Cannot read properties of undefined (reading 'id')
的react-hook-form 错误。
在下面的代码框中,您可以附加一个项目,然后单击Reset
并重置表单。但是在附加项目后单击Back
会产生错误。这个问题只出现在 react-hook-form
代码沙盒:https://codesandbox.io/embed/react-hook-form-reset-usefieldarray-forked-yk7g4?fontsize=14&hidenavigation=1&theme=dark
import React from "react";
import useForm, useFieldArray, Controller from "react-hook-form";
import ReactDOM from "react-dom";
import HeaderBackButton from '@react-navigation/stack';
import "./styles.css";
let renderCount = 0;
function App()
const control, handleSubmit, reset = useForm(
defaultValues:
loadState: "unloaded",
names: []
);
const fields, append = useFieldArray(
control,
name: "names"
);
renderCount++;
return (
<form>
<h1>Field Array </h1>
<p>1. Append using the append button. </p>
<p>2a. reset button works as expected</p>
<p>2b. Back button, which is a HeaderBackButton errors out when there is any change to the field array</p>
<span className="counter">Render Count: renderCount</span>
<HeaderBackButton tintColor='#FFFFFF'
labelVisible=true
onPress=()=>reset()
/>
<button type='button' onClick=()=>reset()>reset</button>
<button type='button' onClick=()=>append('')>append</button>
<ul>
fields.map((item, index) => (
<Controller
key=item.id
render=( field ) => <input ...field />
name=`names[$index]`
control=control
defaultValue=item.lastName
/>
))
</ul>
</form>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
【问题讨论】:
看来作者已经为此提交了一个错误修复。发布后我会更新此线程并且我已经尝试了新版本。 【参考方案1】:验证 react-hook-form 7.22.0 解决了这个问题。
但 7.22.0 中的修复仅使字段数组 undefined
中的所有元素。它没有清除字段数组,这仍然会导致我的具体情况出现问题。
作者发现问题的症结在于异步调用reset
。更新后的sandbox 表明该库的7.22.2 完全解决了该问题。
此代码在 react-hook-form 7.22.2 中按预期工作
import React from "react";
import useForm, useFieldArray, Controller from "react-hook-form";
import ReactDOM from "react-dom";
import HeaderBackButton from "@react-navigation/stack";
import "./styles.css";
let renderCount = 0;
function App()
const getValues, control, reset = useForm(
defaultValues:
loadState: "unloaded",
names: []
);
const fields, append = useFieldArray(
control,
name: "names"
);
renderCount++;
console.log(getValues());
return (
<form>
<h1>Field Array </h1>
<p>1. Append using the append button. </p>
<p>2a. reset button works as expected</p>
<p>
2b. Back button, which is a HeaderBackButton does clear out the
field array now
</p>
<span className="counter">Render Count: renderCount</span>
<HeaderBackButton
tintColor="#FFFFFF"
labelVisible=true
onPress=() => reset( names: [] )
/>
<button type="button" onClick=() => reset( names: [] )>
reset
</button>
<button type="button" onClick=() => append( name: "abc" )>
append
</button>
<ul>
fields.map((item, index) => (
<Controller
key=item.id
render=( field ) => <input value=field.value />
name=`names.$index.name`
control=control
/>
))
</ul>
</form>
);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
【讨论】:
以上是关于在 react-hook-form 的 useFieldArray 上异步调用 reset 时,reset 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
如果输入在材料 ui 对话框中,react-hook-form 的 setValue 方法不起作用
在 react-hook-form 的 useFieldArray 上异步调用 reset 时,reset 无法正常工作