Ich weiß, dass ich die Eingabe nicht mutieren soll und das Objekt klonen soll, um es zu mutieren. Ich folgte der Konvention, die für ein Redux-Starterprojekt verwendet wurde, das Folgendes verwendete:
ADD_ITEM: (state, action) => ({
...state,
items: [...state.items, action.payload.value],
lastUpdated: action.payload.date
})
zum Hinzufügen eines Elements - Ich verwende die Spread-Funktion, um das Element im Array anzuhängen.
Zum Löschen habe ich verwendet:
DELETE_ITEM: (state, action) => ({
...state,
items: [...state.items.splice(0, action.payload), ...state.items.splice(1)],
lastUpdated: Date.now()
})
Dies mutiert jedoch das Eingabestatusobjekt. Ist dies verboten, obwohl ich ein neues Objekt zurückgebe?
javascript
reactjs
redux
CWright
quelle
quelle
items: [...state.items.slice(0, action.payload.value), ...state.items.slice(action.payload.value + 1 )]
Verwenden Sie jetzt Slice anstelle von Splice, um die Eingabe nicht zu mutieren. Ist dies der richtige Weg oder gibt es einen präziseren Weg?Antworten:
Mutiere niemals deinen Zustand.
Auch wenn Sie ein neues Objekt zurückgeben, verschmutzen Sie immer noch das alte Objekt, was Sie niemals tun möchten. Dies macht es problematisch, Vergleiche zwischen dem alten und dem neuen Zustand anzustellen. Zum Beispiel bei
shouldComponentUpdate
dem React-Redux unter der Haube eingesetzt wird. Es macht auch Zeitreisen unmöglich (dh rückgängig machen und wiederholen).Verwenden Sie stattdessen unveränderliche Methoden. Immer benutzen
Array#slice
und niemalsArray#splice
.Ich gehe von Ihrem Code aus, dass dies
action.payload
der Index des Elements ist, das entfernt wird. Ein besserer Weg wäre wie folgt:quelle
...
in der zweiten Anweisung verdoppelt den Inhalt Ihres Statusarr.slice(arr.length)
sollte immer ein leeres Array erzeugen, unabhängig vom Inhaltarr
....
im zweiten Teil -...state.items.slice(action.payload + 1)
Array#slice
gibt ein Array zurück. Um die beiden Slices zu einem einzigen Array zu kombinieren, habe ich den Spread-Operator verwendet. Ohne sie hätten Sie ein Array von Arrays.Mit der Array-Filtermethode können Sie ein bestimmtes Element aus einem Array entfernen, ohne den ursprünglichen Status zu ändern.
Im Kontext Ihres Codes würde es ungefähr so aussehen:
quelle
arr.filter((val, i) => i !== action.payload )
Die ES6-
Array.prototype.filter
Methode gibt ein neues Array mit den Elementen zurück, die den Kriterien entsprechen. Im Kontext der ursprünglichen Frage wäre dies daher:quelle
.filter()
ist keine ES2015-Methode, wurde jedoch in der früheren Version ES5 hinzugefügt.Eine weitere Variante des unveränderlichen "DELETED" -Reduzierers für das Array mit Objekten:
quelle
Die goldene Regel ist, dass wir keinen mutierten Zustand zurückgeben, sondern einen neuen Zustand. Abhängig von der Art Ihrer Aktion müssen Sie möglicherweise Ihren Statusbaum in verschiedenen Formen aktualisieren, wenn er auf den Reduzierer trifft.
In diesem Szenario versuchen wir, ein Element aus einer Statuseigenschaft zu entfernen.
Dies bringt uns zum Konzept der unveränderlichen Update- (oder Datenmodifikations-) Muster von Redux. Unveränderlichkeit ist der Schlüssel, da wir niemals einen Wert im Statusbaum direkt ändern möchten, sondern immer eine Kopie erstellen und einen neuen Wert basierend auf dem alten Wert zurückgeben möchten.
Hier ist ein Beispiel zum Löschen eines verschachtelten Objekts:
Lesen Sie diesen Artikel, um dies besser zu verstehen: https://medium.com/better-programming/deleting-an-item-in-a-nested-redux-state-3de0cb3943da
quelle