Je recherche une fonction pure, pour modifier mon objet d'état immuable. L'état d'origine donné en paramètre doit rester intact. Ceci est particulièrement utile lorsque vous travaillez avec des frameworks tels que Redux et qu'il est beaucoup plus facile de travailler avec immuable object en javascript. D'autant plus que travailler avec l'opérateur de propagation d'objet avec Babel est déjà possible.
Je n'ai rien trouvé de mieux que de copier d'abord l'objet et d'assigner/supprimer la propriété que je veux comme ceci:
function updateState(state, item) {
newState = {...state};
newState[item.id] = item;
return newState;
}
function deleteProperty(state, id) {
var newState = {...state};
delete newState[id];
return newState;
}
Je sens que ça pourrait être plus court
Actions sur l'état, où l'état est considéré comme immuable.
Ajout ou mise à jour de la valeur d'une propriété :
// ES6:
function updateState(state, item) {
return Object.assign({}, state, {[item.id]: item});
}
// With Object Spread:
function updateState(state, item) {
return {
...state,
[item.id]: item
};
}
Suppression d'une propriété
// ES6:
function deleteProperty(state, id) {
var newState = Object.assign({}, state);
delete newState[id];
return newState;
}
// With Object Spread:
function deleteProperty(state, id) {
let {[id]: deleted, ...newState} = state;
return newState;
}
// Or even shorter as helper function:
function deleteProperty({[id]: deleted, ...newState}, id) {
return newState;
}
// Or inline:
function deleteProperty(state, id) {
return (({[id]: deleted, ...state}) => state)(state);
}
Une solution ES6, qui supporte un peu plus, est Object.assign
:
const updateState = (state, item) => Object.assign({}, state, { [item.id]: item });
Dans une fonction de la carte
Pour effectuer ce processus dans une fonction de la carte (supprimer un attribut et ajouter un nouvel attribut à chaque objet), à partir d'un tableau d'objets -
const myArrayOfObjects = [
{id: 1, keyToDelete: 'nonsense'},
{id: 2, keyToDelete: 'rubbish'}
];
Supprimez l'attribut keyToDelete
et ajoutez une nouvelle clé newKey
avec la valeur "someVar"
.
myArrayOfObjects.map(({ keyToDelete, ...item}) => { ...item, newKey:'someVar'});
Mise à jour du tableau pour
[
{id: 1, newKey:'someVar'},
{id: 2, newKey:'someVar'}
]
Voir cet article génial pour plus d'informations sur la méthode de suppression.
Au lieu d'écrire du code passe-partout (comme indiqué ci-dessus: (({[id]: deleted, ...state}) => state)(state)
) qui est difficile à lire, vous pouvez utiliser une bibliothèque pour faire de même:
Par exemple:
import {remove} from 'immutable-modify'
function updateState(state, item) {
return remove(state, item.id)
}
Il prend également en charge les mises à jour imbriquées:
import {set} from 'immutable-modify'
function updateState(state, item) {
return set(state, 'user.products', (products) => ({
...products,
items: products.items.concat(item),
lastUpdate: Date.now()
}))
}