javascript - tutorial - vue.js ejemplos
¿Es esta la forma correcta de eliminar un elemento usando redux? (4)
Sé que se supone que no debo mutar la entrada y debería clonar el objeto para mutarla. Estaba siguiendo la convención utilizada en un proyecto de inicio redux que utilizaba:
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 eliminar 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 devuelva un nuevo objeto?
El método ES6
Array.prototype.filter
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:
DELETE_ITEM: (state, action) => ({
...state,
items: state.items.filter(item => action.payload !== item),
lastUpdated: Date.now()
})
No. Nunca mutes tu estado.
A pesar de que está devolviendo un nuevo objeto, todavía está contaminando el objeto antiguo, lo que nunca quiere hacer.
Esto hace que sea problemático al hacer comparaciones entre el estado antiguo y el nuevo.
Por ejemplo, en
shouldComponentUpdate
que react-redux usa bajo el capó.
También hace que el viaje en el tiempo sea imposible (es decir, deshacer y rehacer).
En cambio, use métodos inmutables.
Utilice siempre
Array#slice
y nunca
Array#splice
.
Asumo por su código que
action.payload
es el índice del elemento que se elimina.
Una mejor manera sería la siguiente:
items: [
...state.items.slice(0, action.payload),
...state.items.slice(action.payload + 1)
],
Otra variante del reductor "DELETED" inmutable para la matriz con objetos:
const index = state.map(item => item.name).indexOf(action.name);
const stateTemp = [
...state.slice(0, index),
...state.slice(index + 1)
];
return stateTemp;
Puede usar el método de filtro de matriz para eliminar un elemento específico de una matriz sin mutar el estado original.
return state.filter(element => element !== action.payload);
En el contexto de su código, se vería así:
DELETE_ITEM: (state, action) => ({
...state,
items: state.items.filter(item => item !== action.payload),
lastUpdated: Date.now()
})