Rimuovere immutabilmente una properties; in un object

Sto usando Redux. Nel mio riduttore cerco di rimuovere una properties; da un object come questo:

const state = { a: '1', b: '2', c: { x: '42', y: '43' }, } 

E voglio avere qualcosa di simile senza wherer mutare lo stato originale:

 const newState = { a: '1', b: '2', c: { x: '42', }, } 

Provai:

 let newState = Object.assign({}, state); delete newState.cy 

ma per alcuni motivi, elimina la properties; di entrambi gli stati.

Potrebbe aiutarmi a farlo?

Trovo i methods di arrays ES5 come filter , map e reduce utile perché restituiscono sempre nuovi arrays o oggetti. In questo caso utilizzare Object.keys per iterare sopra l'object e Array#reduce per riportrlo in un object.

 return Object.assign({}, state, { c: Object.keys(state.c).reduce((result, key) => { if (key !== 'y') { result[key] = state.c[key]; } return result; }, {}) }); 

È ansible utilizzare _.omit(object, [paths]) dalla libreria di lodash

il path può essere nidificato ad esempio: _.omit(object, ['key1.key2.key3'])

Questo perché copia il valore di state.c nell'altro object. E questo valore è un puntatore ad un altro object javascript. Quindi, entrambi i puntatori puntano allo stesso object.

Prova questo:

 let newState = Object.assign({}, state); console.log(newState == state); // false console.log(newState.c == state.c); // true newState.c = Object.assign({}, state.c); console.log(newState.c == state.c); // now it is false delete newState.cy; 

È inoltre ansible eseguire una copia profonda dell'object. Vedi questa domanda e troverai cosa ti è di meglio.

Cosa ne pensi di questo:

 function removeByKey (myObj, deleteKey) { return Object.keys(myObj) .filter(key => key !== deleteKey) .reduce((result, current) => { result[current] = myObj[current]; return result; }, {}); } 

Filtra la chiave che dovrebbe essere eliminata, quindi crea un nuovo object dalle chiavi rimanenti e dall'object iniziale. L'idea è stata rubata da Tyler McGinnes awesome reactjs programma.

JSBin

È facile con Immutable.js :

 const newState = state.deleteIn(['c', 'y']); 

descrizione di deleteIn ()

 function dissoc(key, obj) { copy = Object.assign({}, obj) delete copy[key] return copy } 

Inoltre, se cerchi un toolkit funzionale di programmazione, guarda Ramda .

È ansible utilizzare l'assistente Immutability per distriggersre un attributo nel tuo caso:

 import update from 'immutability-helper'; const updatedState = update(state, { c: { $unset: ['y'] } }); 

Potresti usare i aiutanti di immutabilità di React per sovrascrivere l'integer c se lo hai o per impostare il valore di y in undefined o null . Dipende dal tuo caso di utilizzo per cui può funzionare meglio:

 const newState = update(state, { c: {$set: { x: '42', }}, }); 

o

 const newState2 = update(state, { c: { y: {$set: undefined}, }, });