Estoy usando Redux En mi reductor estoy tratando de eliminar una propiedad de un objeto como este:
const state = {
a: '1',
b: '2',
c: {
x: '42',
y: '43'
},
}
Y quiero tener algo como esto sin tener que mutar el estado original:
const newState = {
a: '1',
b: '2',
c: {
x: '42',
},
}
Lo intenté:
let newState = Object.assign({}, state);
delete newState.c.y
pero por alguna razón, elimina la propiedad de ambos estados.
¿Podría ayudarme a hacer eso?
javascript
immutability
redux
Vincent Taing
fuente
fuente
Object.assign
solo crea una copia superficial destate
y por lo tantostate.c
ynewState.c
apuntará al mismo objeto compartido. Intentó eliminar la propiedady
del objeto compartidoc
y no del nuevo objetonewState
.Respuestas:
¿Qué tal usar la sintaxis de asignación de desestructuración ?
fuente
const deleteProperty = ({[key]: _, ...newObj}, key) => newObj;
. Uso:deleteProperty({a:1, b:2}, "a");
da{b:2}
deep['c']
está vacío, por lo que, en un caso general, es posible que desee agregar una comprobación de la presencia de la clave.Encuentro métodos de arreglos ES5 como
filter
,map
yreduce
útiles porque siempre regreso nuevas matrices u objetos. En este caso, usaríaObject.keys
para iterar sobre el objeto yArray#reduce
volverlo a convertir en un objeto.fuente
myObject
con la clavemyKey
eliminada:Object.keys(myObject).reduce((acc, cur) => cur === myKey ? acc : {...acc, [cur]: myObject[cur]}, {})
Puedes usar
_.omit(object, [paths])
desde la biblioteca lodashLa ruta se puede anidar, por ejemplo:
_.omit(object, ['key1.key2.key3'])
fuente
_.omit
no se pueden eliminar propiedades profundas (lo que OP estaba pidiendo). Hay unomit-deep-lodash
módulo para este propósito._.cloneDeep(obj)
desde lodash. Eso copia el objeto fácilmente y luego simplemente puede usar jsdelete obj.[key]
para eliminar la clave.Solo use la función de desestructuración de objetos ES6
fuente
const {y, ...c} = state.c
podría ser un poco más claro que tener dosc
en el lado izquierdo.const name = 'c'
puede hacerlo yconst {[name]:deletedValue, ...newState} = state
luego regresarnewState
en su reductor. Esto es para una eliminación de clave de nivel superiorEsto se debe a que está copiando el valor de
state.c
al otro objeto. Y ese valor es un puntero a otro objeto javascript. Entonces, ambos punteros apuntan al mismo objeto.Prueba esto:
También puede hacer una copia profunda del objeto. Vea esta pregunta y encontrará lo que es mejor para usted.
fuente
state.c
es una referencia, y la referencia se está copiando muy bien. Redux quiere una forma de estado normalizado, lo que significa usar identificadores en lugar de referencias al anidar el estado. Echa un vistazo a los documentos de redux: redux.js.org/docs/recipes/reducers/NormalizingStateShape.htmlQué tal esto:
Filtra la clave que debe eliminarse y luego crea un nuevo objeto a partir de las claves restantes y el objeto inicial. La idea fue robada del increíble programa de reacciones de Tyler McGinnes.
JSBin
fuente
Además, si busca un kit de herramientas de programación funcional, mire a Ramda .
fuente
Puede usar el ayudante de Inmutabilidad para desarmar un atributo, en su caso:
fuente
A partir de 2019, otra opción es usar el
Object.fromEntries
método. Ha alcanzado la etapa 4.Lo bueno de esto es que maneja bien las teclas enteras.
fuente
Es fácil con Immutable.js :
descripción de deleteIn ()
fuente
El problema que tiene es que no está clonando profundamente su estado inicial. Entonces tienes una copia superficial.
Podrías usar el operador de propagación
O siguiendo tu mismo código
fuente
Normalmente uso
Soy consciente de que no se eliminan realmente la propiedad, pero para casi todos los fines 1 su funcionalmente equivalente. La sintaxis para esto es mucho más simple que las alternativas, que creo que es una muy buena compensación.
1 Si está usando
hasOwnProperty()
, necesitará usar la solución más complicada.fuente
Yo uso este patron
pero en el libro vi otro patrón
fuente
utilidad;))
tipo de acción
creador de acción
reductor
fuente
Como ya se insinuó en algunas de las respuestas, es porque está intentando modificar un estado anidado, es decir. Un nivel más profundo. Una solución canónica sería agregar un reductor a
x
nivel estatal:Reductor de nivel más profundo
Reductor de nivel original
fuente