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.