Quiero proporcionar valores predeterminados en el campo de entrada usando react-hook-form . Primero recupero los datos del usuario del punto final de la API y luego configuro los users de estado para esos datos de usuario. Luego paso los users del estado a los valores predeterminados de defaultValues useForm() .
import React, { useState, useEffect } from "react"; import { useForm } from "react-hook-form"; import axios from "axios"; function LoginFile() { const [users, setUsers] = useState(null); useEffect(() => { axios .get("http://localhost:4000/users/1") .then((res) => setUsers(res.data)); }, []); useEffect(() => { console.log(users); }, [users]); const { register, handleSubmit, errors } = useForm({ defaultValues: users, }); return ( <div> <form onSubmit={handleSubmit(onSubmit)}> Email <input type="email" name="email" ref={register} /><br /> firstname <input name="firstname" ref={register} /><br/> <input type="submit" /> </form> </div> ); } export default LoginFile;Lo hice con el código anterior pero no funcionó como se esperaba. Todos los campos de entrada todavía están vacíos. Quiero tener algunos valores predeterminados en el campo de entrada de mi formulario.
Eso definitivamente funcionó. Usando la API de reinicio y el UseEffect.
Comenzando con picaduras vacías como valores predeterminados y actualizándolas como efectos con el reinicio. Aquí está mi código. Estaba usando TypeScript con Ionic aquí también...
const { control: editControl, handleSubmit: editSubmit, reset } = useForm<EditFormType>({ defaultValues: { question: "", optionA: "", optionB: "", optionC: "", optionD: "", } }); useEffect(() => { let defaults ={ question: editQuestion?.body, optionA: editQuestion?.options[0].body, optionB: editQuestion?.options[1].body, optionC: editQuestion?.options[2].body, optionD: editQuestion?.options[3].body, } reset(defaults) }, [editQuestion, reset])El problema es que durante el primer renderizado, users tienen el valor inicial del gancho useState , que es null . El valor solo cambia después de que finaliza la solicitud axios.get() , que es después del renderizado inicial. Esto significa que los valores predeterminados pasados a useForm son null .
La documentación de defaultValues dice lo siguiente:
Los
defaultValuesse almacenan en caché en el primer renderizado dentro del gancho personalizado. Si desea restablecer losdefaultValues, debe usar la API dereset.
Por lo tanto, solo necesitará usar reset para restablecer el formulario manualmente a los valores que obtiene. La documentación para reset dice lo siguiente:
Deberá pasar
useFormdefaultValuesresetel valor de los componentes delController.
Sin embargo, no está claro en la documentación si null es suficiente como valores predeterminados o si necesita pasarle un objeto adecuado con campos para cada entrada. Para ir a lo seguro, supongamos que es lo último.
El código para hacer esto sería algo como esto:
function LoginFile() { const [users, setUsers] = useState({ email: "", firstname: "" }); const { register, handleSubmit, errors, reset } = useForm({ defaultValues: users, }); useEffect(() => { axios.get("http://localhost:4000/users/1").then((res) => { setUsers(res.data); reset(res.data); }); }, [reset]); useEffect(() => { console.log(users); }, [users]); return ( <div> <form onSubmit={handleSubmit(onSubmit)}> Email <input type="email" name="email" ref={register} /> <br /> firstname <input name="firstname" ref={register} /> <br /> <input type="submit" /> </form> </div> ); } Además, si la única razón para el enlace useState es almacenar el valor de defaultValues , no lo necesita en absoluto y puede limpiar el código para que sea:
function LoginFile() { const { register, handleSubmit, errors, reset } = useForm({ defaultValues: { email: "", firstname: "" }, }); useEffect(() => { axios.get("http://localhost:4000/users/1").then((res) => { reset(res.data); }); }, [reset]); return ( <div> <form onSubmit={handleSubmit(onSubmit)}> Email <input type="email" name="email" ref={register} /> <br /> firstname <input name="firstname" ref={register} /> <br /> <input type="submit" /> </form> </div> ); }