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?

trad
quelle
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 });
}
trad
quelle
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 });
}

vikram jeet singh
quelle
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)
},
Sintaxi
quelle
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 });
},
saulable
quelle
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 :)

Johnatan Maciel
quelle
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
  }
});
Matthew Holtom
quelle
4

Mit ES6 + können Sie einfach [ ${variable}]

Jujhar Singh
quelle
2

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

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

Hoffe das hilft

Catalina
quelle
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.

Javatar
quelle
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

Manoj Patel
quelle
-4

Kann eine Spread-Syntax verwenden, etwa so:

inputChangeHandler : function (event) {
    this.setState( { 
        ...this.state,
        [event.target.id]: event.target.value
    } );
},
sta
quelle
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.