Estou usando o Redux. No meu redutor, estou tentando remover uma propriedade de um objeto como este:
const state = {
a: '1',
b: '2',
c: {
x: '42',
y: '43'
},
}
E eu quero ter algo assim sem ter que alterar o estado original:
const newState = {
a: '1',
b: '2',
c: {
x: '42',
},
}
Eu tentei:
let newState = Object.assign({}, state);
delete newState.c.y
mas por alguns motivos, ele exclui a propriedade dos dois estados.
Poderia me ajudar a fazer isso?
javascript
immutability
redux
Vincent Taing
fonte
fonte
Object.assign
cria apenas uma cópia superficial destate
e, portanto,state.c
enewState.c
irá apontar para o mesmo objeto compartilhado. Você tentou excluir a propriedadey
do objeto compartilhadoc
e não do novo objetonewState
.Respostas:
Que tal usar a sintaxe de atribuição de desestruturação ?
fonte
const deleteProperty = ({[key]: _, ...newObj}, key) => newObj;
. Uso:deleteProperty({a:1, b:2}, "a");
gives{b:2}
deep['c']
estiver vazio; portanto, em um caso geral, convém adicionar uma verificação da presença da chave.Acho ES5 métodos de array como
filter
,map
ereduce
útil, porque eles sempre retornam novas matrizes ou objetos. Nesse caso, eu usariaObject.keys
para iterar o objeto eArray#reduce
transformá-lo novamente em um objeto.fonte
myObject
chavemyKey
removida:Object.keys(myObject).reduce((acc, cur) => cur === myKey ? acc : {...acc, [cur]: myObject[cur]}, {})
Você pode usar
_.omit(object, [paths])
da biblioteca lodashO caminho pode ser aninhado, por exemplo:
_.omit(object, ['key1.key2.key3'])
fonte
_.omit
não é possível excluir propriedades profundas (o que o OP estava pedindo). Háomit-deep-lodash
módulo para esse fim._.cloneDeep(obj)
do lodash. Isso copia o objeto facilmente e você pode simplesmente usar jsdelete obj.[key]
para remover a chave.Basta usar o recurso de desestruturação do objeto ES6
fonte
const {y, ...c} = state.c
pode ser um pouco mais claro do que ter doisc
no lado esquerdo.const name = 'c'
é possívelconst {[name]:deletedValue, ...newState} = state
retornarnewState
no seu redutor. Isto é para uma exclusão de chave de nível superiorIsso ocorre porque você está copiando o valor
state.c
para o outro objeto. E esse valor é um ponteiro para outro objeto javascript. Portanto, os dois ponteiros estão apontando para o mesmo objeto.Tente o seguinte:
Você também pode fazer uma cópia em profundidade do objeto. Veja esta pergunta e você encontrará o que é melhor para você.
fonte
state.c
é uma referência e a referência está sendo copiada muito bem. O Redux deseja uma forma de estado normalizada, o que significa usar IDs em vez de referências ao aninhar o estado. Verifique os documentos do redux: redux.js.org/docs/recipes/reducers/NormalizingStateShape.htmlQue tal agora:
Ele filtra a chave que deve ser excluída e cria um novo objeto a partir das chaves restantes e do objeto inicial. A ideia é roubada do incrível programa reactjs de Tyler McGinnes.
JSBin
fonte
Além disso, se estiver procurando por um kit de ferramentas de programação funcional, consulte o Ramda .
fonte
Você pode usar o Auxiliar de imutabilidade para desabilitar um atributo, no seu caso:
fonte
A partir de 2019, outra opção é usar o
Object.fromEntries
método Atingiu o estágio 4.O bom disso é que ele lida bem com chaves inteiras.
fonte
É fácil com o Immutable.js :
descrição de deleteIn ()
fonte
O problema que você está enfrentando é que você não está clonando profundamente seu estado inicial. Então você tem uma cópia superficial.
Você poderia usar o operador spread
Ou seguindo o mesmo código
fonte
Eu normalmente uso
Sei que isso não é realmente remover a propriedade, mas para quase todos os fins 1 é funcionalmente equivalente. A sintaxe para isso é muito mais simples do que as alternativas que considero uma troca muito boa.
1 Se você estiver usando
hasOwnProperty()
, precisará usar a solução mais complicada.fonte
Eu uso esse padrão
mas no livro eu vi outro padrão
fonte
Utilitário ;))
Tipo de acão
criador de ação
redutor
fonte
Como sugerido em algumas das respostas já, é porque você está tentando modificar um estado aninhado, ou seja. um nível mais profundo. Uma solução canônica seria adicionar um redutor no
x
nível do estado:Redutor de nível mais profundo
Redutor de nível original
fonte