Étant donné un état comme celui-ci:
state = {
things: [
{ id: 'a1', name: 'thing 1' },
{ id: 'a2', name: 'thing 2' },
],
};
Comment créer un nouvel état où l'ID "a1" est supprimé? Il est assez facile de pousser de nouveaux articles:
return state.set(state.get('things').Push(newThing));
Mais je ne peux pas comprendre comment rechercher et supprimer un objet à l'aide de sa propriété id
. J'ai essayé ceci:
return state.set('tracks',
state.get('tracks').delete(
state.get('tracks').findIndex(x => x.get('id') === 'a2')
)
)
Mais cela semble compliqué et ne fonctionne que si l'élément est trouvé, car si findIndex
renvoie -1
, il s'agit d'une valeur valide pour delete
.
Vous pouvez utiliser Array#filter
.
return state.set('things', state.get('things').filter(o => o.get('id') !== 'a1'));
Lorsque vous utilisez le filtre, il répète tous les cycles -> une méthode efficace consiste à rechercher index => slice et à utiliser le séparateur ...
const index = state.findIndex(data => data.id === action.id);
return [...state.slice(0, index), ...state.slice(index + 1)];
Sinon, lorsque vous "recherchez, puis supprimez" ...
var itemIndex = this.state.get("tracks").findIndex(x => x.get('id') === 'a2');
return itemIndex > -1 ? this.state.deleteIn(["tracks", itemIndex]) : this.state;
Cela garantira que l'état n'est pas muté lorsqu'il n'y a pas de changement.
Immutablej est excellent, mais complique les choses dans certains cas Edge, particulièrement lorsque vous travaillez avec des tableaux imbriqués.
Parfois, il est plus facile de revenir à JS dans un sens général pour cette question particulière.
// 1. get a copy of the list into normal JavaScript
const myList = state.getIn(['root', 'someMap', 'myList']).toJS()
// 2. remove item in list using normal JavaScript and/or anything else
myList.splice(deleteIndex, 1)
// 3. return the new state based on mutated myList
return state
.mergeDeep({ root: { someMap: { myList: undefined } }})
.mergeDeep({ root: { someMap: { myList } }})
Malheureusement, l'étape 3 est nécessaire pour définir spécifiquement undefined
car si vous définissez simplement myList
directement comme valeur de tableau, ImmutableJS effectuera une comparaison des valeurs entre la liste actuelle et ne les modifiera que par un comportement étrange.
_ {La justification en est de simplifier la surcharge mentale. Je ne recommande pas de faire cela dans une boucle, mais de manipuler le tableau JS pur dans une boucle si vous devez mais devez être avant l'étape 3.
Vous avez trouvé ce fil en cherchant une solution à une tâche similaire . Le résolu avec update method:
return state.update('things', (things) => things.filter((t) => t.id !== action.things.id))
aucune idée/commentaire lequel est le mieux/préféré?
Vous pouvez le faire même sans immutable.js avec la fonction suivante.
function arrayFilter(array, filter) {
let ret = array
let removed = 0
for (let index = 0; index < array.length; index++) {
const passed = filter(array[index], index, array)
if (!passed) {
ret = [...ret.slice(0, index - removed), ...ret.slice(index - removed + 1)]
removed++
}
}
return ret
}