Hier gibt es drei Antworten, abhängig von der Version von React, mit der Sie arbeiten (gezwungen sind) und ob Sie Hooks verwenden möchten.
Das wichtigste zuerst:
Es ist wichtig zu verstehen , wie funktioniert Reaktion, so dass Sie die Dinge richtig tun können (protip: es ist Super läuft wert durch das Tutorial Übung Reagieren Sie auf die Website Reagieren Es ist gut geschrieben, und deckt alle Grundlagen in einer Weise , dass tatsächlich erklärt , wie zu tun ist . Dinge). "Richtig" bedeutet hier, dass Sie eine Anwendungsoberfläche schreiben, die zufällig in einem Browser gerendert wird. Die gesamte Arbeit an der Benutzeroberfläche erfolgt in React, nicht in "Was Sie gewohnt sind, wenn Sie eine Webseite schreiben" (aus diesem Grund sind React-Apps "Apps", keine "Webseiten").
Reaktionsanwendungen werden aus zwei Gründen gerendert:
- Die Eigenschaften der Komponente, die von dem übergeordneten Element deklariert wurden, erstellen eine Instanz dieser Komponente, die das übergeordnete Element während seines gesamten Lebenszyklus ändern kann
- der interne Status der Komponente, den sie während ihres gesamten Lebenszyklus selbst ändern kann.
Wenn Sie React verwenden, generieren Sie ausdrücklich keine HTML-Elemente und verwenden diese dann: Wenn Sie React anweisen, ein zu verwenden <input>, erstellen Sie beispielsweise kein HTML-Eingabeelement, und Sie weisen React an, ein React-Eingabeobjekt zu erstellen das passiert zu machen als HTML - Eingabeelement, und deren Ereignisbehandlung schaut, aber nicht kontrolliert wird durch das HTML - Element Eingabeereignisse.
Wenn Sie React verwenden, generieren Sie Elemente der Anwendungsbenutzeroberfläche, die dem Benutzer (häufig manipulierbare) Daten präsentieren, wobei die Benutzerinteraktion den Status der Komponente ändert, was dazu führen kann, dass ein Teil Ihrer Anwendungsschnittstelle den neuen Status wiedergibt. In diesem Modell ist der Status immer die letzte Autorität, nicht "welche UI-Bibliothek auch immer zum Rendern verwendet wird", die im Web das DOM des Browsers ist. Das DOM ist in diesem Programmiermodell fast ein nachträglicher Gedanke: Es ist nur das spezielle UI-Framework, das React gerade verwendet.
Im Fall eines Eingabeelements lautet die Logik also:
- Sie geben das Eingabeelement ein,
- Es passiert noch nichts mit Ihrem Eingabeelement. Das Ereignis wurde von React abgefangen und sofort beendet .
- Reagieren Sie, um das Ereignis an die Funktion weiterzuleiten, die Sie für die Ereignisbehandlung eingerichtet haben.
- Diese Funktion kann eine Statusaktualisierung planen.
- Wenn dies der Fall ist, führt React diese Statusaktualisierung aus (asynchron!) und löst
rendernach der Aktualisierung einen Aufruf aus, jedoch nur, wenn die Statusaktualisierung den Status geändert hat .
- Erst nachdem dieses Rendern stattgefunden hat, zeigt die Benutzeroberfläche an, dass Sie "einen Buchstaben eingegeben" haben.
All dies geschieht in wenigen Millisekunden, wenn nicht sogar weniger. Es sieht also so aus, als hätten Sie das Eingabeelement so eingegeben, wie Sie es von "nur ein Eingabeelement auf einer Seite verwenden" gewohnt sind, aber das ist absolut nicht der Fall passierte.
Nachdem dies gesagt wurde, erfahren Sie, wie Sie Werte von Elementen in React erhalten:
Reagieren Sie 15 und darunter mit ES5
Um die Dinge richtig zu machen, hat Ihre Komponente einen Statuswert, der über ein Eingabefeld angezeigt wird. Wir können ihn aktualisieren, indem das UI-Element Änderungsereignisse an die Komponente zurücksendet:
var Component = React.createClass({
getInitialState: function() {
return {
inputValue: ''
};
},
render: function() {
return (
//...
<input value={this.state.inputValue} onChange={this.updateInputValue}/>
//...
);
},
updateInputValue: function(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
Also haben wir das verwenden Reagieren tell updateInputValueFunktion die Interaktion mit dem Benutzer zu handhaben , verwenden , setStateum das Status - Update zu planen, und die Tatsache , dass renderzapft this.state.inputValuebedeutet , dass , wenn es rerenders nach dem Zustand zu aktualisieren, wird der Benutzer des Update Text sehen , auf dem, was sie eingegeben hat .
Nachtrag basierend auf Kommentaren
Angesichts der Tatsache, dass UI-Eingaben Statuswerte darstellen (überlegen Sie, was passiert, wenn ein Benutzer seine Registerkarte auf halbem Weg schließt und die Registerkarte wiederhergestellt wird. Sollten alle von ihnen eingegebenen Werte wiederhergestellt werden? Wenn ja, ist dies der Status). Das könnte Ihnen das Gefühl geben, dass ein großes Formular zehn oder sogar hundert Eingabeformulare benötigt, aber bei React geht es darum, Ihre Benutzeroberfläche auf wartbare Weise zu modellieren: Sie haben nicht 100 unabhängige Eingabefelder, Sie haben Gruppen verwandter Eingaben, also erfassen Sie jedes gruppieren Sie in einer Komponente und bauen Sie dann Ihr "Master" -Formular als Sammlung von Gruppen auf.
MyForm:
render:
<PersonalData/>
<AppPreferences/>
<ThirdParty/>
...
Dies ist auch viel einfacher zu warten als eine riesige Einzelformkomponente. Teilen Sie Gruppen in Komponenten mit Statusverwaltung auf, wobei jede Komponente nur für die Verfolgung einiger Eingabefelder gleichzeitig verantwortlich ist.
Möglicherweise haben Sie auch das Gefühl, dass es "mühsam" ist, den gesamten Code zu schreiben, aber das ist eine falsche Ersparnis: Entwickler, die nicht Sie sind, einschließlich zukünftiger Sie, profitieren tatsächlich stark davon, wenn all diese Eingaben explizit verknüpft werden, weil Dadurch können Codepfade viel einfacher nachverfolgt werden. Sie können jedoch jederzeit optimieren. Sie können beispielsweise einen Statuslinker schreiben
MyComponent = React.createClass({
getInitialState() {
return {
firstName: this.props.firstName || "",
lastName: this.props.lastName || ""
...: ...
...
}
},
componentWillMount() {
Object.keys(this.state).forEach(n => {
let fn = n + 'Changed';
this[fn] = evt => {
let update = {};
update[n] = evt.target.value;
this.setState(update);
});
});
},
render: function() {
return Object.keys(this.state).map(n => {
<input
key={n}
type="text"
value={this.state[n]}
onChange={this[n + 'Changed']}/>
});
}
});
Natürlich gibt es verbesserte Versionen davon. Rufen Sie also https://npmjs.com auf und suchen Sie nach einer Lösung zum Verknüpfen des Reaktionsstatus, die Ihnen am besten gefällt. Bei Open Source geht es hauptsächlich darum, herauszufinden, was andere bereits getan haben, und dies zu verwenden, anstatt alles selbst von Grund auf neu zu schreiben.
Reagiere auf 16 (und 15.5 Übergangs) und 'moderne' JS
Ab React 16 (und Softstart mit 15.5) wird der createClassAufruf nicht mehr unterstützt und die Klassensyntax muss verwendet werden. Dies ändert zwei Dinge: die offensichtliche Klassensyntax, aber auch die thisKontextbindung, createClassdie "kostenlos" ausgeführt werden kann. Um sicherzustellen, dass die Dinge weiterhin funktionieren, stellen Sie sicher, dass Sie die Notation "Fettpfeil" verwenden, um thisanonyme Funktionen in onWhateverHandlern wie z das verwenden onChangewir im code hier:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
inputValue: ''
};
}
render() {
return (
//...
<input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/>
//...
);
},
updateInputValue(evt) {
this.setState({
inputValue: evt.target.value
});
}
});
Möglicherweise haben Sie auch gesehen, dass Benutzer bindin ihrem Konstruktor alle Funktionen zur Ereignisbehandlung wie folgt verwenden:
constructor(props) {
super(props);
this.handler = this.handler.bind(this);
...
}
render() {
return (
...
<element onclick={this.handler}/>
...
);
}
Tu das nicht.
Fast jedes Mal, wenn Sie verwenden bind, gilt das sprichwörtliche "Sie machen es falsch". Ihre Klasse definiert bereits den Objektprototyp und damit bereits den Instanzkontext. Nicht darüber legen bind; Verwenden Sie die normale Ereignisweiterleitung, anstatt alle Ihre Funktionsaufrufe im Konstruktor zu duplizieren, da diese Duplizierung Ihre Fehleroberfläche vergrößert und das Verfolgen von Fehlern erheblich erschwert, da das Problem möglicherweise in Ihrem Konstruktor liegt, anstatt dort, wo Sie Ihren Code aufrufen. Sie müssen auch andere, mit denen Sie arbeiten oder arbeiten möchten, mit Wartungsarbeiten belasten.
Ja, ich weiß, dass die Reaktionsdokumente sagen, dass es in Ordnung ist. Es ist nicht, tu es nicht.
Reagieren Sie 16.8 mit Funktionskomponenten mit Haken
Ab Reaktion 16.8 kann der Funktionskomponente (dh buchstäblich nur einer Funktion, die einige propsals Argument verwendet, so verwendet werden, als ob es sich um eine Instanz einer Komponentenklasse handelt, ohne jemals eine Klasse zu schreiben) auch mithilfe von Hooks der Status zugewiesen werden .
Wenn Sie keinen vollständigen Klassencode benötigen und eine einzelne Instanzfunktion ausreicht, können Sie jetzt mithilfe des useStateHooks eine einzelne Statusvariable und deren Aktualisierungsfunktion abrufen, die ungefähr genauso funktioniert wie die obigen Beispiele, außer ohne der setStateFunktionsaufruf:
import { useState } from 'react';
function myFunctionalComponentFunction() {
const [input, setInput] = useState(''); // '' is the initial state value
return (
<div>
<label>Please specify:</label>
<input value={input} onInput={e => setInput(e.target.value)}/>
</div>
);
}
Früher war die inoffizielle Unterscheidung zwischen Klassen und Funktionskomponenten "Funktionskomponenten haben keinen Status", daher können wir uns nicht mehr dahinter verstecken: Der Unterschied zwischen Funktionskomponenten und Klassenkomponenten ist auf mehreren Seiten im Brunnen verteilt -geschriebene Reaktionsdokumentation (keine Abkürzung für eine Liner-Erklärung, die Sie bequem falsch interpretieren können!), die Sie lesen sollten, damit Sie wissen, was Sie tun, und somit wissen können, ob Sie die beste (was auch immer das für Sie bedeutet) Lösung ausgewählt haben, um sich selbst zu programmieren aus einem Problem heraus, das Sie haben.
this.onSubmit.bind(this);