react setstate no funciona correctamente en bucles

Aug 31 2020

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

3 AwaisRafiqChaudhry Aug 31 2020 at 00:25

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.

1 BhojendraRauniyar Aug 31 2020 at 00:34

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.