Existe-t-il un moyen élégant de supprimer un objet d’un tableau faisant partie d’un tableau? Je travaille avec React et Redux depuis quelque temps déjà, mais je suis bloqué plusieurs heures à chaque fois que je dois supprimer ou insérer des données sans la mutation de l'état.
Le réducteur est un tableau contenant des objets ayant un ID et un autre tableau avec des objets, comme ceci:
[
{ id:123,
items:[
{ id: abc,
name: albert
},
...
]
},
...
]
Je reçois les deux identifiants et j'ai besoin de supprimer l'élément avec l'identifiant abc
.
Pour supprimer un élément d'un tableau par identifiant:
return state.filter(item => item.id !== action.id)
Pour supprimer une clé d'un objet à l'aide de son identifiant:
let copy = Object.assign({}, state) // assuming you use Object.assign() polyfill!
delete copy[action.id] // shallowly mutating a shallow copy is fine
return copy
(Bonus) Idem avec proposition d'opérateur de propagation d'objet :
let { [action.id]: deletedItem, ...rest } = state
return rest
const remove = (state, bucketId, personId) => state.map(
bucket => bucket.id === bucketId
? { ...bucket, items: bucket.items.filter(person => person.id !== personId) }
: bucket,
);
Usage:
const state = [
{
id: 123,
items: [
{
id: 'abc',
name: 'Kinna',
},
{
id: 'def',
name: 'Meggy',
},
],
},
{
id: 456,
items: [
{
id: 'ghi',
name: 'Ade',
},
{
id: 'jkl',
name: 'Tades',
},
],
},
];
console.log(remove(state, 123, 'abc'));
j'ai résolu mon problème de cette façon
if(action.type === "REMOVE_FROM_PLAYLIST"){
let copy = Object.assign({}, state)
delete copy.playlist[action.index].songs[action.indexSongs];
return copy;
}
j'espère que ça aide quelqu'un d'autre.
Vous pouvez également utiliser la méthode omod de lodash .
Sachez que l'importation de lodash augmentera un peu votre taille de construction. Gardez le contrôle un peu en important simplement la méthode spécifique: import omit from 'lodash/omit';
Si possible, je suggère d'utiliser l'opérateur d'étalement d'objet comme décrit dans Réponse de Dan .
Vous pouvez utiliser le trait de soulignement . Il fait exactement ce que vous essayez de faire.
Si vous optez pour le langage Javascript simple, le moyen le plus élégant auquel je puisse penser est d'utiliser Array.prototype.reduce
pour réduire l'état:
var state = [
{ id: 123,
items:[
{ id: 'abc',
name: 'albert'
},
...
]
},
...
]
function filterOut (state) {
return (bucketId, personId) => {
return state.reduce((state, bucket) => {
return state.concat(
(bucketId === bucket.id) ?
Object.assign({}, bucket, {items: bucket.items.filter((person) => person.id !== personId)}) :
bucket
);
}, []);
}
}
var newState = filterOut(state)(123, 'abc');