Saya tahu saya tidak seharusnya mengubah input dan harus mengkloning objek untuk mengubahnya. Saya mengikuti konvensi yang digunakan pada proyek pemula redux yang digunakan:
ADD_ITEM: (state, action) => ({
...state,
items: [...state.items, action.payload.value],
lastUpdated: action.payload.date
})
untuk menambahkan item - Saya menggunakan spread untuk menambahkan item dalam array.
untuk menghapus saya menggunakan:
DELETE_ITEM: (state, action) => ({
...state,
items: [...state.items.splice(0, action.payload), ...state.items.splice(1)],
lastUpdated: Date.now()
})
tetapi ini mengubah objek status input - apakah ini dilarang meskipun saya mengembalikan objek baru?
javascript
reactjs
redux
CWright
sumber
sumber
items: [...state.items.slice(0, action.payload.value), ...state.items.slice(action.payload.value + 1 )]
gunakan slice sekarang sebagai ganti splice agar tidak mengubah input - apakah ini cara yang tepat atau ada cara yang lebih ringkas?Jawaban:
Tidak. Jangan pernah mengubah status Anda.
Meskipun Anda mengembalikan objek baru, Anda masih mencemari objek lama, yang tidak ingin Anda lakukan. Ini membuatnya bermasalah saat melakukan perbandingan antara yang lama dan yang baru. Misalnya di
shouldComponentUpdate
mana react-redux menggunakan di bawah tenda. Itu juga membuat perjalanan waktu menjadi tidak mungkin (yaitu undo dan redo).Sebaliknya, gunakan metode yang tidak dapat diubah. Selalu gunakan
Array#slice
dan jangan pernahArray#splice
.Saya berasumsi dari kode Anda itulah
action.payload
indeks item yang dihapus. Cara yang lebih baik adalah sebagai berikut:sumber
...
dalam pernyataan kedua akan menggandakan konten negara Andaarr.slice(arr.length)
harus selalu menghasilkan larik kosong apa pun isinyaarr
....
di bagian kedua -...state.items.slice(action.payload + 1)
Array#slice
mengembalikan array. Untuk menggabungkan dua irisan menjadi satu larik, saya telah menggunakan operator penyebaran. Tanpa itu, Anda akan memiliki array array.Anda dapat menggunakan metode filter larik untuk menghapus elemen tertentu dari larik tanpa mengubah status aslinya.
Dalam konteks kode Anda, akan terlihat seperti ini:
sumber
arr.filter((val, i) => i !== action.payload )
Array.prototype.filter
Metode ES6 mengembalikan larik baru dengan item yang cocok dengan kriteria. Oleh karena itu, dalam konteks pertanyaan awal, ini adalah:sumber
.filter()
bukan metode ES2015, tetapi telah ditambahkan di versi ES5 sebelumnya.Variasi lain dari peredam "DELETED" yang tidak dapat diubah untuk larik dengan objek:
sumber
Aturan emasnya adalah bahwa kita tidak mengembalikan keadaan yang bermutasi, melainkan keadaan baru. Bergantung pada jenis tindakan Anda, Anda mungkin perlu memperbarui pohon status Anda dalam berbagai bentuk saat mencapai peredam.
Dalam skenario ini kami mencoba untuk menghapus item dari properti negara.
Hal ini membawa kita pada konsep pola pembaruan (atau modifikasi data) yang tidak dapat diubah dari Redux. Kekekalan adalah kuncinya karena kita tidak pernah ingin secara langsung mengubah nilai dalam pohon status, tetapi selalu membuat salinan dan mengembalikan nilai baru berdasarkan nilai lama.
Berikut adalah contoh cara menghapus objek bersarang:
Untuk memahami ini lebih baik, pastikan untuk membaca artikel ini: https://medium.com/better-programming/deleting-an-item-in-a-nested-redux-state-3de0cb3943da
sumber