Reactjs setState () avec un nom de clé dynamique?


248

EDIT: ceci est un doublon, voir ici

Je ne trouve aucun exemple d'utilisation d'un nom de clé dynamique lors de la définition de l'état. Voici ce que je veux faire:

inputChangeHandler : function (event) {
    this.setState( { event.target.id  : event.target.value } );
},

où event.target.id est utilisé comme clé d'état à mettre à jour. N'est-ce pas possible dans React?


4
Il s'agit d'un double de toute question concernant les clés d'objets dynamiques. Ce n'est pas spécifique de réagir
Cory Danielson

9
var newstate = {}; newstate [event.target.id] = event.target.id; this.setState (newstate);
Cory Danielson

Merci, je n'avais pas une bonne maîtrise de l'utilisation des objets en général.
trad


@trad Je suis avec ce problème mais, qu'avez-vous mis sur votre état initial? Ce n'est pas grave, non?
Raphael Onofre

Réponses:


280

Grâce à l'indice de @ Cory, j'ai utilisé ceci:

inputChangeHandler : function (event) {
    var stateObject = function() {
      returnObj = {};
      returnObj[this.target.id] = this.target.value;
         return returnObj;
    }.bind(event)();

    this.setState( stateObject );    
},

Si vous utilisez ES6 ou le transpilateur Babel pour transformer votre code JSX, vous pouvez également effectuer cela avec des noms de propriété calculés :

inputChangeHandler : function (event) {
    this.setState({ [event.target.id]: event.target.value });
    // alternatively using template strings for strings
    // this.setState({ [`key${event.target.id}`]: event.target.value });
}

27
Il y a aussi une nouvelle syntaxe pour cela, si vous utilisez bablejs pour construire votre code. Vous pouvez utilisercomputed property names
Cory Danielson

La deuxième approche provoque une erreur de syntaxe dans les navigateurs sur Windows (IE, Chrome). Quelqu'un l'a-t-il remarqué?
benjaminz

comment se déclarer?
Muneem Habib

Merci trad, c'est ce que je cherchais pour éviter la duplication de code pour l' <Radio />implémentation.
Adesh M

6
Si vous définissez un état en utilisant le nom de propriété calculé comme ceci: this.setState({ [event.target.id]: event.target.value });alors comment accéderiez-vous à cet état en utilisant this.state......?
user3574492

142

Lorsque vous devez gérer plusieurs éléments d'entrée contrôlés, vous pouvez ajouter un attribut de nom à chaque élément et laisser la fonction de gestionnaire choisir quoi faire en fonction de la valeur de event.target.name.

Par exemple:

inputChangeHandler(event) {
  this.setState({ [event.target.name]: event.target.value });
}


7
qu'indiquent les crochets autour de [event.target.name]? Pourquoi sont-ils nécessaires?
user798719

1
Par rapport à l'approche habituelle pour nommer chaque élément séparément comme this.setState ({userName: e.target.value}); Cela gérera plusieurs éléments de forme comme un tableau et pas besoin de définir chaque élément individuel
vikram jeet singh

1
mais comment accéder à cet état de la même manière? comme this.state([event.target.name])?
Kirankumar Dafda

1
Je pense que les documents Web MDN et cet article expliquent pourquoi nous avons besoin des supports.
Kelli

46

Comment j'ai accompli cela ...

inputChangeHandler: function(event) {
  var key = event.target.id
  var val = event.target.value
  var obj  = {}
  obj[key] = val
  this.setState(obj)
},

J'ai fait de même, mais le problème était qu'il ne rendait toujours pas le composant, et j'ai couru pilier pour poster (y compris ceci: D), et quelque part trouvé ceci: ce this.forceUpdate();qui n'aurait pas dû être le cas avec la dernière React. Voyons quel est le problème plus tard !!
xploreraj

24

Je voulais juste ajouter que vous pouvez également utiliser la déstructuration pour refactoriser le code et le rendre plus net.

inputChangeHandler: function ({ target: { id, value }) {
    this.setState({ [id]: value });
},

10

En boucle avec un .maptravail comme celui-ci:

{
    dataForm.map(({ id, placeholder, type }) => {
        return <Input
            value={this.state.type}
            onChangeText={(text) => this.setState({ [type]: text })}
            placeholder={placeholder}
            key={id} />
    })
}

Notez le paramètre []in type. J'espère que cela t'aides :)


10

J'avais un problème similaire.

Je voulais définir l'état de stockage de la clé de 2e niveau dans une variable.

par exemple this.setState({permissions[perm.code]: e.target.checked})

Cependant, ce n'est pas une syntaxe valide.

J'ai utilisé le code suivant pour y parvenir:

this.setState({
  permissions: {
    ...this.state.permissions,
    [perm.code]: e.target.checked
  }
});


2

Je cherchais une solution jolie et simple et j'ai trouvé ceci:

this.setState({ [`image${i}`]: image })

J'espère que cela t'aides


1
this.setState({ [`${event.target.id}`]: event.target.value}, () => {
      console.log("State updated: ", JSON.stringify(this.state[event.target.id]));
    });

Veuillez noter le caractère de citation.


0

Votre état avec dictionnaire met à jour une clé sans perdre d'autre valeur

state = 
{   
    name:"mjpatel"  
    parsedFilter:
    {
      page:2,
      perPage:4,
      totalPages: 50,
    }
}

La solution est ci-dessous

 let { parsedFilter } = this.state
 this.setState({
      parsedFilter: {
        ...this.state.parsedFilter,
        page: 5
      }
  });

ici mettre à jour la valeur de la "page" clé avec la valeur 5


-4

Peut utiliser une syntaxe étendue, quelque chose comme ceci:

inputChangeHandler : function (event) {
    this.setState( { 
        ...this.state,
        [event.target.id]: event.target.value
    } );
},

7
React fera fusionner l'objet pour vous, c'est une mauvaise pratique.
Rohmer

1
Fondamentalement, si vous avez un objet interne et que vous souhaitez modifier une propriété sur cet objet interne, vous le faites comme ceci: this.setState ({selectedItems: {... selectedItems, [item.id]: true}})
Eran Or
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.