Estoy usando react-hook-form y react-navigation. En mi caso de uso, uso useFieldArray para controlar una variedad creciente de entradas y quiero reset el formulario cuando el usuario presiona HeaderBackButton . Pero cuando paso el reset a onPress prop de HeaderBackButton y presiono el botón, los errores de forma de gancho reaccionan con Cannot read properties of undefined (reading 'id') cada vez que hay algún cambio en la matriz de campo. En el cuadro de código a continuación, puede agregar un elemento y hacer clic en Reset y restablecer el formulario. Pero hacer clic en Back después de agregar un elemento produciría el error. Este problema solo aparece en forma de gancho de reacción < 7.22.0
CodeSandbox: 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);Verificado que react-hook-form 7.22.0 soluciona este problema.
Pero la solución en 7.22.0 solo hace que todos los elementos en la matriz de campos no estén undefined . No borra la matriz de campos, lo que sigue causando problemas en mi caso específico.
El autor ha identificado que el quid del problema es llamar al reset de forma asíncrona. Un sandbox actualizado demuestra que 7.22.2 de la biblioteca soluciona el problema por completo.
Este código funciona como se esperaba con 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);