React Setstate funktioniert bei Loops nicht richtig

Aug 31 2020

Ich erhalte eine Validierungsantwort von meinem Backend als Array wie dieses

 [
        { param: "secondName", msg: "second name is required" },
        { param: "password", msg: "password is required" }
 ]

und ich habe einen Zustand in meiner Reaktionskomponente wie diesen

  const [errs, setErrs] = useState({
    firstName: null,
    secondName: null,
    password: null,
    email: null,
  })

Ziel ist es, in meinem Bundesstaat nur die in meinem response.paramsFormular genannten Felder einzureichen und den Rest so zu belassen, wie er ist null. das habe ich versucht:

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`
};

Das Problem ist jedoch, dass nur das letzte Element in meinem "Fehlerstatus" geändert wird. Ausgabe ist:

{
    first: null,
    second: null,
    password: 'password is required',
    email: null,
}

ps: ich habe es mit vanilla js versucht, indem ich das Array durchlaufen und Errs objs Requisiten direkt auf die response.msg gesetzt habe und es hat funktioniert. Das Problem muss also mit dem Reaktionszustand sein

Antworten

3 AwaisRafiqChaudhry Aug 31 2020 at 00:25

Verwenden Sie den Fat Arrow-Ansatz, um den Status wie folgt festzulegen:

setLocalErrs(localErrs => ({ ...localErrs, [single.param]: single.msg }));

Es vermeidet Zustandsverluste, wenn die Setterfunktion aufgrund unterschiedlicher asynchroner Aufrufe usw. zweimal gleichzeitig aufgerufen wird.

1 BhojendraRauniyar Aug 31 2020 at 00:34

Vermeiden Sie es, den Status in einer Schleife zu aktualisieren . Status aktualisieren wie:

let errObj = {}
res.forEach((single) => {
  errObj[single.param] = single.msg
})
setLocalErrs({
  ...localErrs,
  ...errObj
})

Übrigens können Sie einfach verwenden:

setLocalErrs(errObj)

Da errObjhat alle Werte aktualisiert.