J'ai un problème où le rendu de l'état provoque des problèmes d'interface utilisateur et il a été suggéré de ne mettre à jour qu'une valeur spécifique dans mon réducteur afin de réduire le nombre de rendus de rendu sur une page.
c'est un exemple de mon état
{
name: "some name",
subtitle: "some subtitle",
contents: [
{title: "some title", text: "some text"},
{title: "some other title", text: "some other text"}
]
}
et je suis en train de le mettre à jour comme ça
case 'SOME_ACTION':
return { ...state, contents: action.payload }
où action.payload
est un tableau complet contenant de nouvelles valeurs. Mais maintenant, je dois juste mettre à jour le texte du deuxième élément du tableau de contenu, et quelque chose comme ça ne marche pas
case 'SOME_ACTION':
return { ...state, contents[1].text: action.payload }
où action.payload
est maintenant un texte dont j'ai besoin pour la mise à jour.
Vous pouvez utiliser les aides React Immutability
import update from 'react-addons-update';
// ...
case 'SOME_ACTION':
return update(state, {
contents: {
1: {
text: {$set: action.payload}
}
}
});
Bien que j'imagine que vous feriez probablement quelque chose de plus semblable?
case 'SOME_ACTION':
return update(state, {
contents: {
[action.id]: {
text: {$set: action.payload}
}
}
});
Vous pouvez utiliser map
. Voici un exemple d'implémentation:
case 'SOME_ACTION':
return {
...state,
contents: state.contents.map(
(content, i) => i === 1 ? {...content, text: action.payload}
: content
)
}
Vous n'êtes pas obligé de tout faire en une seule ligne:
case 'SOME_ACTION':
const newState = { ...state };
newState.contents =
[
newState.contents[0],
{title: newState.contnets[1].title, text: action.payload}
];
return newState
Très tard pour le parti mais voici une solution générique qui fonctionne avec chaque valeur d'index.
Vous créez et répartissez un nouveau tableau à partir de l’ancien tableau jusqu’à la index
que vous souhaitez modifier.
Ajoutez les données que vous voulez.
Créez et étendez un nouveau tableau à partir de la variable index
que vous souhaitez modifier jusqu'à la fin du tableau.
let index=1;// probabbly action.payload.id
case 'SOME_ACTION':
return {
...state,
contents: [
...state.contents.slice(0,index),
{title: "some other title", text: "some other text"},
...state.contents.slice(index+1)
]
}
Dans mon cas, j'ai fait quelque chose comme ça, basé sur la réponse de Luis:
...State object...
userInfo = {
name: '...',
...
}
...Reducer's code...
case CHANGED_INFO:
return {
...state,
userInfo: {
...state.userInfo,
// I'm sending the arguments like this: changeInfo({ id: e.target.id, value: e.target.value }) and use them as below in reducer!
[action.data.id]: action.data.value,
},
};
Je crois que lorsque vous avez besoin de ce type d'opérations sur votre état Redux , l'opérateur de diffusion est votre ami et ce principe s'applique à tous les enfants.
Supposons que ceci est votre état:
const state = {
houses: {
gryffindor: {
points: 15
},
ravenclaw: {
points: 18
},
hufflepuff: {
points: 7
},
slytherin: {
points: 5
}
}
}
Et vous voulez ajouter 3 points à Serdaigle
const key = "ravenclaw";
return {
...state, // copy state
houses: {
...state.houses, // copy houses
[key]: { // update one specific house (using Computed Property syntax)
...state.houses[key], // copy that specific house's properties
points: state.houses[key].points + 3 // update its `points` property
}
}
}
En utilisant l'opérateur spread, vous ne pouvez mettre à jour que le nouvel état, en laissant tout le reste intact.
Exemple tiré de ceci article étonnant , vous pouvez trouver presque toutes les options possibles avec d'excellents exemples.