Sé que se supone que no debo mutar la entrada y debo clonar el objeto para mutarlo. Estaba siguiendo la convención utilizada en un proyecto de inicio redux que usaba:
ADD_ITEM: (state, action) => ({
...state,
items: [...state.items, action.payload.value],
lastUpdated: action.payload.date
})
para agregar un elemento: obtengo el uso de spread para agregar el elemento en la matriz.
para borrar utilicé:
DELETE_ITEM: (state, action) => ({
...state,
items: [...state.items.splice(0, action.payload), ...state.items.splice(1)],
lastUpdated: Date.now()
})
pero esto está mutando el objeto de estado de entrada, ¿está prohibido aunque estoy devolviendo un nuevo objeto?
javascript
reactjs
redux
CWright
fuente
fuente
items: [...state.items.slice(0, action.payload.value), ...state.items.slice(action.payload.value + 1 )]
usar cortar ahora en lugar de empalmar para no mutar la entrada: ¿es este el camino a seguir o hay una manera más concisa?Respuestas:
No. Nunca mutes tu estado.
A pesar de que está devolviendo un objeto nuevo, todavía está contaminando el objeto anterior, lo que nunca querrá hacer. Esto hace que sea problemático al hacer comparaciones entre el estado antiguo y el nuevo. Por ejemplo, en el
shouldComponentUpdate
que react-redux se usa debajo del capó. También hace imposible viajar en el tiempo (es decir, deshacer y rehacer).En su lugar, use métodos inmutables. Utilizar siempre
Array#slice
y nuncaArray#splice
.Supongo de su código que
action.payload
es el índice del elemento que se elimina. Una mejor forma sería la siguiente:fuente
...
en la segunda declaración duplicará el contenido de su estadoarr.slice(arr.length)
siempre debe producir una matriz vacía sin importar el contenido dearr
....
en la segunda parte?...state.items.slice(action.payload + 1)
Array#slice
devuelve una matriz. Para combinar los dos cortes en una sola matriz, he usado el operador de extensión. Sin él, tendría una matriz de matrices.Puede utilizar el método de filtro de matriz para eliminar un elemento específico de una matriz sin alterar el estado original.
En el contexto de su código, se vería así:
fuente
arr.filter((val, i) => i !== action.payload )
El
Array.prototype.filter
método ES6 devuelve una nueva matriz con los elementos que coinciden con los criterios. Por lo tanto, en el contexto de la pregunta original, esto sería:fuente
.filter()
no es un método ES2015, pero se ha agregado en la versión anterior ES5.Otra variación del reductor inmutable "ELIMINADO" para la matriz con objetos:
fuente
La regla de oro es que no devolvemos un estado mutado, sino un nuevo estado. Dependiendo del tipo de su acción, es posible que deba actualizar su árbol de estado en varias formas cuando llegue al reductor.
En este escenario, estamos intentando eliminar un elemento de una propiedad estatal.
Esto nos lleva al concepto de patrones inmutables de actualización (o modificación de datos) de Redux. La inmutabilidad es clave porque nunca queremos cambiar directamente un valor en el árbol de estado, sino que siempre queremos hacer una copia y devolver un valor nuevo basado en el valor anterior.
A continuación, se muestra un ejemplo de cómo eliminar un objeto anidado:
Para comprender esto mejor, asegúrese de consultar este artículo: https://medium.com/better-programming/deleting-an-item-in-a-nested-redux-state-3de0cb3943da
fuente