controlled und uncontrolled inputs in React

Die erste React-App entsteht und ein simples Textinput soll schnell eingefügt werden, <input type="text" id="someId" /> ist schnell in die render()-Funktion aufgenommen, die App wird gestartet, ihr wollt testen – und nichts passiert. Kein Text erscheint, wenn ihr tippt – oder vorhandener Text wird nicht verändert. Willkommen in React und controlled und uncontrolled inputs.

controlled und uncontrolled inputs in React

Was bedeutet das nun für uns? Schreiben wir normales HTML, dann übernimmt der Browser das Speichern des aktuellen Wertes im Input. Auf das können wir dann bequem via let inputValue = document.getElementById('someId').value zugreifen und weiter verwenden. Dieses Verhalten ist uncontrolled, da die Elemente ihren eigenen State definieren und diesen im UI anzeigen.

React geht den Weg von controlled inputs, was heißt, dass wir den State manuell updaten müssen, da das UI nur den State widerspiegelt, der in render() vorgegeben wird. Schauen wir uns diesen Code an:

render() {
  return <text input="text"
               id="someId"
               value={ this.state.text } />
}

this.state.text kann initial natürlich auch ein leerer String sein. Wird die Website nun aufgerufen und etwas in das Textinput getippt, dann re-rendered React den Ursprungszustand erneut und der initiale Wert von this.state.text wird wieder eingetragen. So sieht es aus, als würden unsere Eingaben gar nicht berücksichtigt.

Change Handler für Inputs

Was wir benötigen, ist ein Change Handler. Eine Methode, die aufgerufen wird, wenn sich der Wert des Textinputs ändert. In dieser Methode muss dann der State angepasst werden, denn der neue State wird beim re-render dann auch angezeigt, da es nun der aktuelle State ist.

constructor(props) {
  super(props);

  // Initialer Wert wird auf leeren String gesetzt
  // Da im ES6-Style von React kein automatisches Binding von 'this' durchgeführt wird,
  // müssen wir den Context von 'this' im ChangeHandler manuell auf den Kontext der class setzen.
  this.state = { value: '' };
  this.handleChange = this.handleChange.bind(this);
}

handleChange(event) {
  // Via React's setState() wird der state aktualisiert und bei jeder Änderung im Textinput aktualisiert
  this.setState({ value: event.target.value });
}

render() {
  return (
    <input type="text" value={ this.state.value } onChange={ this.handleChange } />
  );
}

Die Kommentare zu den Zeilen sind inline. Der Teil im constructor setzt den initialen state und bindet den this-Kontext an die Klasse, da ansonsten im ES6-Stil das aufrufende Element this repräsentiert. Aber wieder zu unserem Problem, in der render()-Methode geben wir dem Textinput eine onChange-Methode die bei jeder Änderung des Inputs aufgerufen wird. In diesem Handler wird mit dem aktuellen Wert via setState() der state aktualisiert. Beim nächsten re-render wird nun der neue state genutzt und dargestellt. Das Textinput aktualisiert sich.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.