Ich habe eine Menge react
Code gelesen und sehe solche Dinge, die ich nicht verstehe:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
Ich habe eine Menge react
Code gelesen und sehe solche Dinge, die ich nicht verstehe:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
Antworten:
Das ist eine Curry-Funktion
Untersuchen Sie diese Funktion zunächst mit zwei Parametern…
Hier ist es wieder in Curryform…
Hier ist der gleiche 1 Code ohne Pfeilfunktionen…
Konzentrieren Sie sich auf
return
Es könnte hilfreich sein, es anders zu visualisieren. Wir wissen, dass Pfeilfunktionen so funktionieren - achten wir besonders auf den Rückgabewert .
Unsere
add
Funktion gibt also eine Funktion zurück - wir können Klammern für zusätzliche Klarheit verwenden. Der fettgedruckte Text ist der Rückgabewert unserer Funktionadd
Mit anderen Worten,
add
eine Zahl gibt eine Funktion zurückCurry-Funktionen aufrufen
Um unsere Curry-Funktion nutzen zu können, müssen wir sie etwas anders nennen…
Dies liegt daran, dass der erste (äußere) Funktionsaufruf eine zweite (innere) Funktion zurückgibt. Erst nachdem wir die zweite Funktion aufgerufen haben, erhalten wir tatsächlich das Ergebnis. Dies wird deutlicher, wenn wir die Anrufe auf zwei Leitungen trennen ...
Wenden Sie unser neues Verständnis auf Ihren Code an
OK, jetzt, da wir verstehen, wie das funktioniert, schauen wir uns Ihren Code an
Wir beginnen damit, es ohne Pfeilfunktionen darzustellen…
Da Pfeilfunktionen jedoch lexikalisch binden
this
, würde es tatsächlich eher so aussehen…Vielleicht können wir jetzt klarer sehen, was dies bewirkt. Die
handleChange
Funktion erstellt eine Funktion für eine bestimmtefield
. Dies ist eine praktische Reaktionstechnik, da Sie für jeden Eingang eigene Listener einrichten müssen, um den Anwendungsstatus zu aktualisieren. Mit derhandleChange
Funktion können wir den gesamten duplizierten Code entfernen, der zum Einrichten vonchange
Listenern für jedes Feld führen würde. Cool!1 Hier musste ich nicht lexikalisch binden,
this
da die ursprünglicheadd
Funktion keinen Kontext verwendet, daher ist es in diesem Fall nicht wichtig, sie beizubehalten.Noch mehr Pfeile
Bei Bedarf können mehr als zwei Pfeilfunktionen sequenziert werden -
Curry-Funktionen können überraschen. Im Folgenden wird
$
eine Curry-Funktion mit zwei Parametern definiert. Am Aufrufort scheint es jedoch so, als könnten wir eine beliebige Anzahl von Argumenten liefern. Currying ist die Abstraktion von Arity -Teilanwendung
Teilanwendung ist ein verwandtes Konzept. Es ermöglicht uns, Funktionen, ähnlich wie beim Curry, teilweise anzuwenden, außer dass die Funktion nicht in Curry-Form definiert werden muss -
Hier ist eine funktionierende Demo, mit der
partial
Sie in Ihrem eigenen Browser spielen können -quelle
$
wurde verwendet, um das Konzept zu demonstrieren , aber Sie können es benennen, was Sie wollen. Zufällig, aber völlig unabhängig,$
wurde es in populären Bibliotheken wie jQuery verwendet, wo$
es eine Art globaler Einstiegspunkt für die gesamte Funktionsbibliothek ist. Ich denke, es wurde auch in anderen verwendet. Eine andere, die Sie sehen werden, ist_
in Bibliotheken wie Unterstrich und Lodash populär. Kein Symbol ist aussagekräftiger als das andere. Sie weisen die Bedeutung für Ihr Programm zu. Es ist einfach gültiges JavaScript: D$
wie es verwendet wird. Wenn Sie nach der Implementierung selbst fragen,$
handelt es sich um eine Funktion, die einen Wert empfängtx
und eine neue Funktion zurückgibtk => ...
. Wenn wirk (x)
uns den Körper der zurückgegebenen Funktion ansehen, sehen wir, dass wir wissen, dassk
es auch eine Funktion sein muss, und was auch immer das Ergebnis vonk (x)
ist, wird zurückgesetzt$ (...)
, von dem wir wissen, dass es eine andere zurückgibtk => ...
, und weiter geht es ... Wenn Sie immer noch sind stecken bleiben, lass es mich wissen.abc(1,2,3)
ist weniger als ideal alsabc(1)(2)(3)
. Es ist schwieriger, über die Logik des Codes nachzudenken, und es ist schwierig, die Funktion abc zu lesen, und es ist schwieriger, den Funktionsaufruf zu lesen. Bevor Sie nur wissen mussten, was abc tut, sind Sie sich jetzt nicht sicher, welche unbenannten Funktionen abc zurückgibt, und zwar zweimal.Wenn Sie die verfügbaren Syntaxen von Pfeilfunktionen verstehen, können Sie verstehen, welches Verhalten sie einführen, wenn sie wie in den von Ihnen bereitgestellten Beispielen verkettet sind.
Wenn eine Pfeilfunktion ohne Klammern mit oder ohne mehrere Parameter geschrieben wird, wird implizit der Ausdruck zurückgegeben, der den Funktionskörper bildet . In Ihrem Beispiel ist dieser Ausdruck eine weitere Pfeilfunktion.
Ein weiterer Vorteil des Schreibens anonymer Funktionen mithilfe der Pfeilsyntax besteht darin, dass sie lexikalisch an den Bereich gebunden sind, in dem sie definiert sind. Aus 'Pfeilfunktionen' auf MDN :
Dies ist in Ihrem Beispiel besonders relevant, wenn man bedenkt, dass es aus a stammt reagierenAnwendung. Wie Wie von @naomik, Reaktion in oft Sie einen Zugriff auf Komponente Member - Funktionen verwenden
this
. Zum Beispiel:quelle
Ein allgemeiner Tipp: Wenn Sie durch eine neue JS-Syntax und deren Kompilierung verwirrt sind, können Sie babel überprüfen . Wenn Sie beispielsweise Ihren Code in babel kopieren und die Voreinstellung es2015 auswählen, erhalten Sie eine Ausgabe wie diese
quelle
Stellen Sie sich das so vor: Jedes Mal, wenn Sie einen Pfeil sehen, ersetzen Sie ihn durch
function
.function parameters
werden vor dem Pfeil definiert.Also in Ihrem Beispiel:
und dann zusammen:
Aus den Dokumenten :
quelle
this
.Kurz und einfach 🎈
Es ist eine Funktion, die eine andere kurz geschriebene Funktion zurückgibt.
Warum Leute es tun ❓
Haben Sie sich gestellt, wenn Sie eine Funktion schreiben müssen, die angepasst werden kann? Oder Sie müssen eine Rückruffunktion schreiben, die feste Parameter (Argumente) hat, aber Sie müssen mehr Variablen an die Funktion übergeben, aber globale Variablen vermeiden? Wenn Sie mit " Ja " antworten , ist dies die richtige Vorgehensweise.
Zum Beispiel haben wir einen
button
Rückruf mit onClick. Und wir müssen anid
die Funktion übergeben,onClick
akzeptieren aber nur einen Parameterevent
, wir können keine zusätzlichen Parameter wie folgt übergeben:Es wird nicht funktionieren!
Deshalb machen wir eine Funktion, die andere Funktionen mit ihrem eigenen Variablenbereich ohne globale Variablen zurückgibt, weil globale Variablen böse sind 😈.
Unten wird die Funktion
handleClick(props.id)}
aufgerufen und eine Funktion zurückgegeben, dieid
in ihrem Umfang liegt! Unabhängig davon, wie oft gedrückt wird, wirken sich die IDs nicht gegenseitig aus oder ändern sich gegenseitig. Sie sind vollständig isoliert.quelle
Das Beispiel in Ihrer Frage ist das von a,
curried function
dasarrow function
einimplicit return
für das erste Argument verwendet und hat .Die Pfeilfunktion bindet dies lexikalisch, dh sie haben kein eigenes
this
Argument, sondern übernehmen denthis
Wert aus dem umschließenden BereichEin Äquivalent des obigen Codes wäre
Eine weitere Sache, die Sie an Ihrem Beispiel beachten sollten, ist die Definition
handleChange
als Konstante oder Funktion. Wahrscheinlich verwenden Sie es als Teil einer Klassenmethode und es verwendet aclass fields syntax
Anstatt die äußere Funktion direkt zu binden, binden Sie sie im Klassenkonstruktor
Eine andere Sache, die im Beispiel zu beachten ist, ist der Unterschied zwischen impliziter und expliziter Rückgabe.
Oben ist ein Beispiel für implizite Rückgabe, dh. Es nimmt das Wertefeld als Argument und gibt das Ergebnis zurück,
field*2
das die zurückzugebende Funktion explizit angibtBei einer expliziten Rückgabe würden Sie die Methode explizit anweisen, den Wert zurückzugeben
Eine andere Sache, die Sie bei Pfeilfunktionen beachten sollten, ist, dass sie keine eigenen haben,
arguments
sondern diese auch vom Umfang der Eltern erben.Zum Beispiel, wenn Sie nur eine Pfeilfunktion wie definieren
Alternativ bieten Pfeilfunktionen die Restparameter, die Sie verwenden können
quelle
Es mag nicht vollständig verwandt sein, aber da die erwähnte Frage "React Use Case" (und ich stoße immer wieder auf diesen SO-Thread): Es gibt einen wichtigen Aspekt der Doppelpfeilfunktion, der hier nicht explizit erwähnt wird. Nur der 'erste' Pfeil (Funktion) wird benannt (und somit durch die Laufzeit 'unterscheidbar'), alle folgenden Pfeile sind anonym und zählen aus Sicht von React bei jedem Rendern als 'neues' Objekt.
Somit bewirkt die Doppelpfeilfunktion, dass jede PureComponent ständig neu gerendert wird.
Beispiel
Sie haben eine übergeordnete Komponente mit einem Änderungshandler wie folgt:
und mit einem Render wie:
{ tasks.map(task => <MyTask handleChange={this.handleChange(task)}/> }
handleChange wird dann für eine Eingabe oder einen Klick verwendet. Und das alles funktioniert und sieht sehr gut aus. ABER es bedeutet, dass jede Änderung, die das übergeordnete Element zum erneuten Rendern veranlasst (wie eine völlig unabhängige Statusänderung), auch ALLE Ihre MyTask neu rendert, obwohl es sich um PureComponents handelt.
Dies kann auf viele Arten gelindert werden, z. B. indem Sie den 'äußersten' Pfeil und das Objekt, mit dem Sie ihn füttern würden, übergeben oder eine benutzerdefinierte shouldUpdate-Funktion schreiben oder zu den Grundlagen zurückkehren, z. B. benannte Funktionen schreiben (und diese manuell binden ...).
quelle