web-dev-qa-db-fra.com

Comment mettre à jour une valeur unique dans un élément de tableau spécifique dans Redux

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 }

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 }

action.payload est maintenant un texte dont j'ai besoin pour la mise à jour.

77
Ilja

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}
      }
    }
  });
44
Clarkie

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
       )
    }
133
Fatih Erikli

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
14
Yuya

Très tard pour le parti mais voici une solution générique qui fonctionne avec chaque valeur d'index.

  1. Vous créez et répartissez un nouveau tableau à partir de l’ancien tableau jusqu’à la index que vous souhaitez modifier.

  2. Ajoutez les données que vous voulez.

  3. 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)
         ]
    }
2
Ivan V.

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,
  },
};

1
Erfan226

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.

0
Luis Rodriguez