web-dev-qa-db-fra.com

Mettre à jour l'un des objets du tableau, de manière immuable

Dans Rea.'s this.state, j'ai une propriété appelée formErrors contenant le tableau d'objets dynamique suivant.

[
  {fieldName: 'title', valid: false}, 
  {fieldName: 'description', valid: true},
  {fieldName: 'cityId', valid: false},
  {fieldName: 'hostDescription', valid: false},
]

Supposons que je devrais mettre à jour l'objet state ayant le nom de champ cityId sur la valeur valide de true.

Quel est le moyen le plus simple ou le plus courant de résoudre ce problème?

Je peux utiliser l'une des bibliothèques immutability-helper , immutable-js etc ou ES6. Cela fait plus de 4 heures que j'essaie de faire des recherches sur Google et que je n'arrive toujours pas à comprendre. Serait extrêmement reconnaissant pour une aide.

15
Fellow Stranger

Vous pouvez utiliser map pour itérer les données et rechercher le nom de champ. Si nom de champ est cityId, vous devez modifier la valeur et retourner un nouvel objet sinon, simplement return le même object.

Écris-le comme ceci:

var data = [
    {fieldName: 'title', valid: false}, 
    {fieldName: 'description', valid: true},
    {fieldName: 'cityId', valid: false},
    {fieldName: 'hostDescription', valid: false},
]

var newData = data.map(el => {
                  if(el.fieldName == 'cityId')
                     return Object.assign({}, el, {valid:true})
                  return el
              });

this.setState({ data: newData }); 
19
Mayank Shukla

Que diriez-vous de immutability-helper ? Fonctionne très bien. Vous recherchez la commande $merge je pense.

@FellowStranger: J'ai une (et une seule) section de mon état redux qui est un tableau d'objets. J'utilise l'index dans le réducteur pour mettre à jour l'entrée correcte:

case EMIT_DATA_TYPE_SELECT_CHANGE:
  return state.map( (sigmap, index) => {
    if ( index !== action.payload.index ) {
      return sigmap;
    } else {
      return update(sigmap, {$merge: {
        data_type: action.payload.value
      }})
    }
})

Franchement, c'est un peu gras, et j'ai l'intention de changer cette partie de mon objet state, mais ça fonctionne ... Il ne semble pas que vous utilisiez redux, mais la tactique devrait être similaire.

1
Omortis

Au lieu de stocker vos valeurs dans un tableau, je vous suggère fortement d'utiliser un objet afin de pouvoir facilement spécifier l'élément que vous souhaitez mettre à jour. Dans l'exemple ci-dessous, la clé est le nom du champ, mais il peut s'agir de n'importe quel identifiant unique

var fields = {
    title: {
        valid: false
    },
    description: {
        valid: true
    }
}

alors vous pouvez utiliser la fonction update de immutability-helper:

var newFields = update(fields, {title: {valid: {$set: true}}})
1
FuzzyTree

Voici un exemple - ES6

Le left est le code et le right le résultat.

 enter image description here

Voici le code ci-dessous

const data = [
    { fieldName: 'title', valid: false }, 
    { fieldName: 'description', valid: true },
    { fieldName: 'cityId', valid: false }, // old data
    { fieldName: 'hostDescription', valid: false },
]

const newData = data.map(obj => {
  if(obj.fieldName === 'cityId') // check if fieldName equals to cityId
     return {
       ...obj,
       valid: true,
       description: 'You can also add more values here' // Example of data extra fields
     }
  return obj
});

const result = { data: newData }; 

console.log(result);

this.setState({ data: newData });

J'espère que cela vous aidera, Bon codage!

0