Reactjs setState () mit einem dynamischen Schlüsselnamen?


248

EDIT: Dies ist ein Duplikat, siehe hier

Ich kann keine Beispiele für die Verwendung eines dynamischen Schlüsselnamens beim Festlegen des Status finden. Folgendes möchte ich tun:

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

Dabei wird event.target.id als zu aktualisierender Statusschlüssel verwendet. Ist das in React nicht möglich?


4
Dies ist ein Duplikat aller Fragen zu dynamischen Objektschlüsseln. Es ist nicht spezifisch zu reagieren
Cory Danielson

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

Vielen Dank, ich hatte keinen guten Überblick über die Verwendung von Objekten im Allgemeinen.
Trad


@trad Ich bin mit diesem Problem, aber was hast du auf deinen Ausgangszustand gesetzt? Es ist egal, oder?
Raphael Onofre

Antworten:


280

Dank des Hinweises von @ Cory habe ich Folgendes verwendet:

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

    this.setState( stateObject );    
},

Wenn Sie ES6 oder den Babel-Transpiler zum Transformieren Ihres JSX-Codes verwenden, können Sie dies auch mit berechneten Eigenschaftsnamen erreichen :

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
Es gibt auch eine neue Syntax dafür, wenn Sie bablejs verwenden, um Ihren Code zu erstellen. Sie können verwendencomputed property names
Cory Danielson

Der zweite Ansatz verursacht Syntaxfehler in Browsern unter Windows (IE, Chrome). Hat jemand bemerkt?
Benjamin

Wie werde ich angegeben?
Muneem Habib

Vielen Dank trad, das ist es, wonach ich gesucht habe, um Codeduplizierungen für die <Radio />Implementierung zu vermeiden .
Adesh M

6
Wenn Sie einen Status mit dem berechneten Eigenschaftsnamen wie folgt festlegen: this.setState({ [event.target.id]: event.target.value });Wie würden Sie dann mit auf diesen Status zugreifen this.state......?
user3574492

142

Wenn Sie mehrere gesteuerte Eingabeelemente verarbeiten müssen, können Sie jedem Element ein Namensattribut hinzufügen und die Handlerfunktion basierend auf dem Wert von event.target.name auswählen lassen, was zu tun ist.

Beispielsweise:

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


7
Was bedeuten die Klammern um [event.target.name]? Warum werden sie benötigt?
user798719

1
Im Vergleich zum üblichen Ansatz, jedes Element separat wie folgt zu benennen: setState ({userName: e.target.value}); Dies behandelt mehrere Elemente der Form als Array und es ist nicht erforderlich, jedes einzelne Element
festzulegen

1
Aber wie kann ich trotzdem auf dieselbe Weise auf diesen Status zugreifen? wie this.state([event.target.name])?
Kirankumar Dafda

1
Ich denke, MDN-Webdokumente und dieser Beitrag erklären, warum wir die Klammern brauchen.
Kelli

46

Wie ich das geschafft habe ...

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

Ich habe es auf ähnliche Weise gemacht, aber das Problem war, dass die Komponente immer noch nicht gerendert wurde, und ich habe eine Säule zum Posten ausgeführt (einschließlich dieser: D), und irgendwo habe ich Folgendes gefunden: this.forceUpdate();was bei der neuesten Reaktion nicht der Fall sein sollte. Mal sehen, was das Problem später ist !!
Xploreraj

24

Ich wollte nur hinzufügen, dass Sie auch die De-Strukturierung verwenden können, um den Code umzugestalten und ihn übersichtlicher aussehen zu lassen.

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

10

Im Einklang mit dieser .mapArbeit:

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

Beachten Sie die []in typeParameter. Hoffe das hilft :)


10

Ich hatte ein ähnliches Problem.

Ich wollte den Status festlegen, in dem der Schlüssel der 2. Ebene in einer Variablen gespeichert ist.

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

Dies ist jedoch keine gültige Syntax.

Ich habe den folgenden Code verwendet, um dies zu erreichen:

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


2

Ich suchte nach einer hübschen und einfachen Lösung und fand diese:

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

Hoffe das hilft


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

Bitte beachten Sie das Anführungszeichen.


0

Ihr Status mit Wörterbuch aktualisiert einige Schlüssel, ohne anderen Wert zu verlieren

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

Lösung ist unten

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

hier Wert für Schlüssel "Seite" mit Wert 5 aktualisieren


-4

Kann eine Spread-Syntax verwenden, etwa so:

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

7
React führt das Zusammenführen des Objekts für Sie durch. Dies ist eine schlechte Vorgehensweise.
Rohmer

1
Wenn Sie ein inneres Objekt haben und eine Eigenschaft für dieses innere Objekt ändern möchten, gehen Sie wie folgt vor: this.setState ({selectedItems: {... selectedItems, [item.id]: true}})
Eran Or.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.