react setstate tidak bekerja dengan baik pada loop

Aug 31 2020

saya mendapatkan respons validasi dari backend saya sebagai array seperti ini

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

dan saya memiliki keadaan di komponen reaksi saya seperti ini

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

Tujuannya adalah untuk mengubah keadaan saya, hanya bidang yang disebutkan dalam response.paramsformulir yang saya kirimkan dan biarkan sisanya apa adanya null. ini yang saya coba:

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

tapi masalahnya adalah itu hanya mengubah item terakhir dalam "keadaan yang salah"; keluarannya adalah:

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

ps: saya mencobanya dengan vanilla js dengan melakukan perulangan melalui array dan menyetel alat peraga Errs obj langsung ke response.msg dan berhasil. Jadi masalahnya harus dengan react setstate

Jawaban

3 AwaisRafiqChaudhry Aug 31 2020 at 00:25

Coba gunakan pendekatan Fat Arrow untuk mengatur keadaan sebagai berikut:

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

Ini menghindari kehilangan status jika fungsi setter dipanggil dua kali pada saat yang sama karena panggilan asinkron yang berbeda, dll.

1 BhojendraRauniyar Aug 31 2020 at 00:34

Hindari memperbarui status dalam satu lingkaran . Perbarui status seperti:

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

Ngomong-ngomong, Anda cukup menggunakan:

setLocalErrs(errObj)

Karena errObjmemiliki semua nilai negara yang diperbarui.