Je sais que je ne suis pas censé muter l'entrée et que je devrais cloner l'objet pour le muter. Je suivais la convention utilisée sur un projet de démarrage redux qui utilisait:
ADD_ITEM: (state, action) => ({
...state,
items: [...state.items, action.payload.value],
lastUpdated: action.payload.date
})
pour ajouter un élément - je reçois l'utilisation de spread pour ajouter l'élément dans le tableau.
pour supprimer j'ai utilisé:
DELETE_ITEM: (state, action) => ({
...state,
items: [...state.items.splice(0, action.payload), ...state.items.splice(1)],
lastUpdated: Date.now()
})
mais cela mute l'objet d'état d'entrée - est-ce interdit même si je retourne un nouvel objet?
javascript
reactjs
redux
CWright
la source
la source
items: [...state.items.slice(0, action.payload.value), ...state.items.slice(action.payload.value + 1 )]
utiliser slice maintenant au lieu de splice afin de ne pas muter l'entrée - est-ce la voie à suivre ou y a-t-il une manière plus concise?Réponses:
Non, ne changez jamais votre état.
Même si vous renvoyez un nouvel objet, vous polluez toujours l'ancien, ce que vous ne voulez jamais faire. Cela rend problématique lors des comparaisons entre l'ancien et le nouvel état. Par exemple dans
shouldComponentUpdate
lequel react-redux utilise sous le capot. Cela rend également impossible le voyage dans le temps (c'est-à-dire annuler et refaire).Utilisez plutôt des méthodes immuables. Utilisez toujours
Array#slice
et jamaisArray#splice
.Je suppose que de votre code
action.payload
est l'index de l'élément en cours de suppression. Une meilleure façon serait la suivante:la source
...
dans la deuxième instruction doublera également le contenu de votre étatarr.slice(arr.length)
doit toujours produire un tableau vide quel que soit le contenu dearr
....
dans la deuxième partie -...state.items.slice(action.payload + 1)
Array#slice
renvoie un tableau. Pour combiner les deux tranches en un seul tableau, j'ai utilisé l'opérateur de propagation. Sans cela, vous auriez un tableau de tableaux.Vous pouvez utiliser la méthode de filtre de tableau pour supprimer un élément spécifique d'un tableau sans modifier l'état d'origine.
Dans le contexte de votre code, cela ressemblerait à ceci:
la source
arr.filter((val, i) => i !== action.payload )
La
Array.prototype.filter
méthode ES6 renvoie un nouveau tableau avec les éléments qui correspondent aux critères. Par conséquent, dans le contexte de la question initiale, ce serait:la source
.filter()
n'est pas une méthode ES2015, mais a été ajoutée dans la version précédente ES5.Une autre variante du réducteur immuable "DELETED" pour le tableau avec des objets:
la source
La règle d'or est que nous ne retournons pas un état muté, mais plutôt un nouvel état. Selon le type de votre action, vous devrez peut-être mettre à jour votre arborescence d'états sous diverses formes lorsqu'elle atteint le réducteur.
Dans ce scénario, nous essayons de supprimer un élément d'une propriété d'état.
Cela nous amène au concept des modèles de mise à jour immuable (ou de modification de données) de Redux. L'immuabilité est essentielle car nous ne voulons jamais changer directement une valeur dans l'arborescence d'état, mais plutôt toujours faire une copie et renvoyer une nouvelle valeur basée sur l'ancienne valeur.
Voici un exemple de suppression d'un objet imbriqué:
Pour mieux comprendre cela, assurez-vous de consulter cet article: https://medium.com/better-programming/deleting-an-item-in-a-nested-redux-state-3de0cb3943da
la source