react setstate no funciona correctamente en bucles
obtengo una respuesta de validación de mi backend como una matriz como esta
[
{ param: "secondName", msg: "second name is required" },
{ param: "password", msg: "password is required" }
]
y tengo un estado en mi componente de reacción como este
const [errs, setErrs] = useState({
firstName: null,
secondName: null,
password: null,
email: null,
})
El objetivo es cambiar en mi estado solo los campos mencionados en mi response.paramsformulario de envío y dejar el resto tal como están null. esto es lo que intenté:
const submitFoo = () => {
console.log(localErrs) //all props are set to null (default)
res.forEach((single) => {
setLocalErrs({
...localErrs,
[single.param]: single.msg
});
});
console.log(localErrs);//only password is set to the `response.msg`, instead of `password` AND `secondName`
};
pero el problema es que solo está cambiando el último elemento en mi "estado de error"; la salida es:
{
first: null,
second: null,
password: 'password is required',
email: null,
}
ps: lo probé con vanilla js recorriendo la matriz y configurando los accesorios de Errs obj directamente en response.msg y funcionó. entonces proplem debe ser con react setstate
Respuestas
Intente usar el enfoque Fat Arrow para establecer el estado de la siguiente manera:
setLocalErrs(localErrs => ({ ...localErrs, [single.param]: single.msg }));
Evita la pérdida de estado en caso de que la función de establecimiento se llame dos veces al mismo tiempo debido a diferentes llamadas asíncronas, etc.
Evite actualizar el estado en un bucle . Actualizar estado como:
let errObj = {}
res.forEach((single) => {
errObj[single.param] = single.msg
})
setLocalErrs({
...localErrs,
...errObj
})
Por cierto, simplemente puedes usar:
setLocalErrs(errObj)
Dado que errObjtiene todos los valores de estados actualizados.