在 react-hook-form 的 useFieldArray 上异步调用 reset 时,reset 无法正常工作

When reset is called asynchronously on react-hook-form's useFieldArray, reset doesn't work correctly

我正在使用 react-hook-form 和 react-navigation。在我的用例中,我使用 useFieldArray 来控制不断增长的输入数组,并且我想在用户按下 HeaderBackButtonreset 表单。但是当我将 reset 传递给 HeaderBackButtononPress 道具并按下按钮时,只要字段数组有任何变化,就会出现 Cannot read properties of undefined (reading 'id') 的 react-hook-form 错误。 在下面的代码框中,您可以附加一个项目,然后单击 Reset 并重置表单。但是在附加项目后单击 Back 会产生错误。这个问题只出现在react-hook-form < 7.22.0

代码沙箱: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);

已验证 react-hook-form 7.22.0 修复了这个问题。

但 7.22.0 中的修复仅使字段数组中的所有元素 undefined。它没有清除字段数组,这仍然导致我的具体情况出现问题。

作者已确定问题的症结在于异步调用 reset。库的更新 sandbox demonstrates that 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);