Ich benutze Redux. In meinem Reduzierer versuche ich, eine Eigenschaft aus einem Objekt wie diesem zu entfernen:
const state = {
a: '1',
b: '2',
c: {
x: '42',
y: '43'
},
}
Und ich möchte so etwas haben, ohne den ursprünglichen Zustand mutieren zu müssen:
const newState = {
a: '1',
b: '2',
c: {
x: '42',
},
}
Ich habe es versucht:
let newState = Object.assign({}, state);
delete newState.c.y
Aus bestimmten Gründen wird die Eigenschaft jedoch aus beiden Zuständen gelöscht.
Könnte mir dabei helfen?
javascript
immutability
redux
Vincent Taing
quelle
quelle
Object.assign
nur eine flache Kopie von und erstellt wirdstate
und daher auf dasselbe gemeinsam genutzte Objekt verweist. Sie haben versucht, die Eigenschaft aus dem freigegebenen Objekt und nicht aus dem neuen Objekt zu löschen .state.c
newState.c
y
c
newState
Antworten:
Wie wäre es mit der Verwendung der Destrukturierungszuweisungssyntax ?
quelle
const deleteProperty = ({[key]: _, ...newObj}, key) => newObj;
. Verwendung:deleteProperty({a:1, b:2}, "a");
gibt{b:2}
deep['c']
es leer ist. In einem allgemeinen Fall möchten Sie möglicherweise eine Überprüfung auf das Vorhandensein des Schlüssels hinzufügen.Ich finde ES5 Array Methoden wie
filter
,map
undreduce
nützlich , weil sie immer neue Arrays oder Objekte zurück. In diesem Fall würde ichObject.keys
das Objekt durchlaufen undArray#reduce
es wieder in ein Objekt verwandeln.quelle
myObject
mitmyKey
entferntem Schlüssel zu erhalten :Object.keys(myObject).reduce((acc, cur) => cur === myKey ? acc : {...acc, [cur]: myObject[cur]}, {})
Sie können
_.omit(object, [paths])
aus der lodash Bibliothek verwendenPfad kann zum Beispiel verschachtelt sein:
_.omit(object, ['key1.key2.key3'])
quelle
_.omit
können keine tiefen Eigenschaften gelöscht werden (was OP gefragt hat). Es gibt einomit-deep-lodash
Modul für diesen Zweck._.cloneDeep(obj)
von lodash. Das kopiert das Objekt einfach und dann können Sie einfach js verwendendelete obj.[key]
, um den Schlüssel zu entfernen.Verwenden Sie einfach die ES6-Objektzerstörungsfunktion
quelle
const {y, ...c} = state.c
könnte etwas klarer sein als zweic
auf der linken Seite.const name = 'c'
dann können Sie Sieconst {[name]:deletedValue, ...newState} = state
dann zurücknewState
in Ihrem Minderer. Dies ist für eine Schlüssellöschung der obersten EbeneDas liegt daran, dass Sie den Wert von kopieren
state.c
auf das andere Objekt . Und dieser Wert ist ein Zeiger auf ein anderes Javascript-Objekt. Beide Zeiger zeigen also auf dasselbe Objekt.Versuche dies:
Sie können das Objekt auch tief kopieren. Sehen Sie sich diese Frage an und finden Sie heraus, was für Sie am besten ist.
quelle
state.c
ist eine Referenz, und die Referenz wird einwandfrei kopiert. Redux möchte eine normalisierte Statusform, dh beim Verschachteln des Status werden IDs anstelle von Referenzen verwendet. Schauen Sie sich die Redux-Dokumente an: redux.js.org/docs/recipes/reducers/NormalizingStateShape.htmlWie wäre es damit:
Es filtert den Schlüssel, der gelöscht werden soll, und erstellt dann ein neues Objekt aus den verbleibenden Schlüsseln und dem ursprünglichen Objekt. Die Idee wurde Tyler McGinnes fantastischem Reaktionsprogramm gestohlen.
JSBin
quelle
Wenn Sie nach einem Toolkit für die funktionale Programmierung suchen, schauen Sie sich auch Ramda an .
quelle
Sie können den Unveränderlichkeitshelfer verwenden, um ein Attribut zu deaktivieren. In Ihrem Fall:
quelle
Ab 2019 besteht eine weitere Option darin, die
Object.fromEntries
Methode zu verwenden. Es hat Stufe 4 erreicht.Das Schöne daran ist, dass es ganzzahlige Schlüssel gut handhabt.
quelle
Mit Immutable.js ist das ganz einfach :
Beschreibung von deleteIn ()
quelle
Das Problem, das Sie haben, ist, dass Sie Ihren Ausgangszustand nicht tief klonen. Sie haben also eine flache Kopie.
Sie können den Spread-Operator verwenden
Oder folgen Sie demselben Code
quelle
Ich benutze normalerweise
Mir ist klar, dass dies nicht das Eigentum entfernt, sondern für fast alle Zwecke 1 funktional gleichwertig. Die Syntax dafür ist viel einfacher als die Alternativen, die ich für einen ziemlich guten Kompromiss halte.
1 Wenn Sie verwenden
hasOwnProperty()
, müssen Sie die kompliziertere Lösung verwenden.quelle
Ich benutze dieses Muster
aber im Buch sah ich ein anderes Muster
quelle
Nützlichkeit ;))
Aktionstyp
Aktionsersteller
Reduzierstück
quelle
Wie bereits in einigen Antworten angedeutet, liegt dies daran, dass Sie versuchen, einen verschachtelten Status zu ändern, d. H. eine Ebene tiefer. Eine kanonische Lösung wäre, einen Reduzierer auf
x
staatlicher Ebene hinzuzufügen :Tieferer Reduzierer
Original Pegelreduzierer
quelle