Estoy creando una página para que el usuario actualice sus datos personales con React-Hook-Form. Una vez que se carga paginado, uso useEffect
para obtener los datos personales actuales del usuario y establecerlos en el valor predeterminado del formulario.
Puse el valor obtenido en defaultValue
of <Controller />
. Sin embargo, simplemente no se muestra en el cuadro de texto. Aquí está mi código:
import React, {useState, useEffect, useCallback} from 'react'; import { useForm, Controller } from 'react-hook-form' import { URL } from '../constants'; const UpdateUserData = props => { const [userData, setUserData] = useState(null); const { handleSubmit, control} = useForm({mode: 'onBlur'}); const fetchUserData = useCallback(async account => { const userData = await fetch(`${URL}/user/${account}`) .then(res=> res.json()); console.log(userData); setUserData(userData); }, []); useEffect(() => { const account = localStorage.getItem('account'); fetchUserData(account); }, [fetchUserData]) const onSubmit = async (data) => { // TODO } return ( <div> <form onSubmit={handleSubmit(onSubmit)}> <div> <label>User Name:</label> <Controller as={<input type='text' />} control={control} defaultValue={userData ? userData.name : ''} name='name' /> </div> <div> <label>Phone:</label> <Controller as={<input type='text' />} control={control} defaultValue={userData ? userData.phone : ''} name='phone' /> </div> <button>Submit</button> </form> </div> ); } export default UpdateUserData;
La API llamada funciona bien y el valor se establece userData
en el estado de datos de usuario.
{ name: "John", phone: "02-98541566" ... }
También intenté establecerUserData con datos simulados en setUserData
useEffect()
, y tampoco funciona. ¿Hay algún problema en mi código anterior?
Puede usar setValue ( https://react-hook-form.com/api/useform/setvalue ).
Importarlo desde useForm:
const { handleSubmit, control, setValue} = useForm({ mode: 'onBlur' });
Luego llámelo con los datos del usuario después de que se reciba:
useEffect(() => { if (userData) { setValue([ { name: userData.name }, { phone: userData.phone } ]); } }, [userData]);
Puede eliminar los valores predeterminados del formulario.
EDITAR: vea las respuestas alternativas a continuación si esto no funciona.
setValue
no funcionó para mí. Alternativamente, puede usar el método de reset
:
Restablezca todo el estado del formulario o parte del estado del formulario.
Aquí está el código de trabajo:
/* registered address */ const [registeredAddresses, setRegisteredAddresses] = useState([]); const { register, errors, handleSubmit, reset } = useForm <FormProps> ({ validationSchema: LoginSchema, }); /** * get addresses data */ const getRegisteredAddresses = async () => { try { const addresses = await AddressService.getAllAddress(); setRegisteredAddresses(addresses); setDataFetching(false); } catch (error) { setDataFetching(false); } }; useEffect(() => { getRegisteredAddresses(); }, []); useEffect(() => { if (registeredAddresses) { reset({ addressName: registeredAddresses[0].name, tel: registeredAddresses[0].contactNumber }); } }, [registeredAddresses]);
El formato del parámetro setValue de @tommcandrew no funcionó para mí.
Este formato hizo:
useEffect(() => { const object = localStorage.getItem('object'); setValue("name", object.name); }, [])
aunque esta publicación tiene 2 meses, me topé con este problema hoy y busqué un par de formas de hacerlo. La forma más efectiva que se me ocurrió es usar useMemo para establecer sus valores predeterminados, así:
const { control, errors, handleSubmit } = useForm({ reValidateMode: 'onChange', defaultValues: useMemo(() => yourDefaultValues, [yourDefaultValues]), });
Esto le permite establecer correctamente los valores en su formulario, sin la lucha de múltiples implementaciones si tiene matrices de campo (que fue mi caso).
Esto también funciona mientras se usa el ejemplo de componente de formulario inteligente avanzado de la documentación oficial. Hazme saber si tienes alguna pregunta !
La respuesta de @tam está a la mitad de lo que se necesita para que funcione con la versión 6.8.3.
Debe proporcionar el valor predeterminado pero también usarEffect para restablecer. Se requiere esa distinción particular si tiene un formulario que recarga con otra entidad. Tengo un ejemplo completo en CodeSanbox aquí .
En pocas palabras: debe definir sus valores predeterminados en el userForm
de usuario.
const { register, reset, handleSubmit } = useForm({ defaultValues: useMemo(() => { return props.user; }, [props]) });
Entonces necesitas escuchar el cambio potencial.
useEffect(() => { reset(props.user); }, [props.user]);
El ejemplo en Code Sandbox permite intercambiar entre dos usuarios y hacer que el formulario cambie sus valores.
Encontré otra manera fácil, utilicé la API de reset
de useForm
const { handleSubmit, register, reset } = useForm({ resolver });
Después de llamar a la API y obtener los datos de respuesta, llame al reset
con nuevos apiData, asegúrese de que las claves de apiData sean las mismas que las claves de entrada (atributo de nombre):
useEffect(() => { reset(apiData); }, [apiData]);
Los valores predeterminados del formulario se almacenan en caché y, por lo tanto, una vez que obtiene los datos de la API, restablecemos el estado del formulario con nuevos datos.
Esto funciona para objetos anidados (estoy usando la versión 6.15.1)
useEffect(() => { for (const [key, value] of Object.entries(data)) { setValue(key, value, { shouldValidate: true, shouldDirty: true }) } }, [data])