J'ai lu un tas de react
code et je vois des trucs comme ça que je ne comprends pas:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
J'ai lu un tas de react
code et je vois des trucs comme ça que je ne comprends pas:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
Réponses:
C'est une fonction curry
Examinons d'abord cette fonction avec deux paramètres…
Le voici à nouveau au curry…
Voici le même code 1 sans fonction de flèche…
Se concentrer sur
return
Cela pourrait aider à le visualiser d'une autre manière. Nous savons que les fonctions fléchées fonctionnent comme ceci - accordons une attention particulière à la valeur de retour .
Notre
add
fonction renvoie donc une fonction - nous pouvons utiliser des parenthèses pour plus de clarté. Le texte en gras est la valeur de retour de notre fonctionadd
En d'autres termes, un
add
certain nombre renvoie une fonctionAppel de fonctions au curry
Donc pour utiliser notre fonction curry, il faut l'appeler un peu différemment…
En effet, le premier appel de fonction (externe) renvoie une seconde fonction (interne). Ce n'est qu'après avoir appelé la deuxième fonction que nous obtenons réellement le résultat. C'est plus évident si nous séparons les appels sur deux lignes…
Appliquer notre nouvelle compréhension à votre code
OK, maintenant que nous comprenons comment cela fonctionne, regardons votre code
On va commencer par le représenter sans utiliser les fonctions flèches…
Cependant, comme les fonctions fléchées se lient lexicalement
this
, cela ressemblerait en fait à ceci…Peut-être que maintenant nous pouvons voir ce que cela fait plus clairement. La
handleChange
fonction crée une fonction pour un spécifiéfield
. Il s'agit d'une technique React pratique car vous devez configurer vos propres écouteurs sur chaque entrée afin de mettre à jour l'état de vos applications. En utilisant lahandleChange
fonction, nous pouvons éliminer tout le code dupliqué qui entraînerait la configuration d'change
écouteurs pour chaque champ. Cool!1 Ici, je n'ai pas eu à lier lexicalement
this
parce que laadd
fonction d' origine n'utilise aucun contexte, il n'est donc pas important de la conserver dans ce cas.Encore plus de flèches
Plus de deux fonctions flèches peuvent être séquencées, si nécessaire -
Les fonctions au curry sont capables de surprendre les choses. Ci-dessous, nous voyons
$
défini comme une fonction curry avec deux paramètres, mais sur le site de l'appel, il semble que nous pouvons fournir un nombre illimité d'arguments. Le curry est l'abstraction de l' arité -Application partielle
L'application partielle est un concept connexe. Il nous permet d'appliquer partiellement des fonctions, similaires au curry, sauf que la fonction n'a pas à être définie sous forme de curry -
Voici une démonstration de travail avec laquelle
partial
vous pouvez jouer dans votre propre navigateur -la source
$
été utilisé pour faire une démonstration du concept, mais vous pouvez le nommer comme vous le souhaitez. Par coïncidence mais complètement sans rapport,$
a été utilisé dans des bibliothèques populaires comme jQuery, où$
est en quelque sorte le point d'entrée global de la bibliothèque entière de fonctions. Je pense que cela a également été utilisé dans d'autres. Un autre que vous verrez est_
, popularisé dans des bibliothèques comme le soulignement et le lodash. Aucun symbole n'a plus de sens qu'un autre; vous attribuez la signification de votre programme. C'est tout simplement du JavaScript valide: D$
en regardant comment il est utilisé. Si vous posez des questions sur l'implémentation elle-même,$
est une fonction qui reçoit une valeurx
et renvoie une nouvelle fonctionk => ...
. En regardant le corps de la fonction renvoyée, nous voyonsk (x)
donc nous savons quek
doit également être une fonction, et quel que soit le résultat de celui-cik (x)
est réinjecté$ (...)
, ce que nous savons en retourne une autrek => ...
, et ainsi de suite ... Si vous êtes toujours coincé, faites le moi savoir.abc(1,2,3)
est moins qu'idéal queabc(1)(2)(3)
. Il est plus difficile de raisonner sur la logique du code et il est difficile de lire la fonction abc et il est plus difficile de lire l'appel de fonction. Avant, vous n'aviez besoin que de savoir ce que fait abc, maintenant vous n'êtes pas sûr des fonctions sans nom que retourne abc, et deux fois.Comprendre les syntaxes disponibles des fonctions fléchées vous permettra de comprendre le comportement qu'elles introduisent lorsqu'elles sont "enchaînées" comme dans les exemples que vous avez fournis.
Lorsqu'une fonction de flèche est écrite sans accolades de bloc, avec ou sans plusieurs paramètres, l'expression qui constitue le corps de la fonction est implicitement renvoyée. Dans votre exemple, cette expression est une autre fonction de flèche.
Un autre avantage de l'écriture de fonctions anonymes à l'aide de la syntaxe fléchée est qu'elles sont liées lexicalement à l'étendue dans laquelle elles sont définies. Depuis «Fonctions fléchées» sur MDN :
Ceci est particulièrement pertinent dans votre exemple étant donné qu'il est tiré d'un reactjsapplication. Comme l'a souligné @naomik, dans React, vous accédez souvent aux fonctions membres d' un composant à l' aide de
this
. Par exemple:la source
Une astuce générale, si vous êtes confus par l'une des nouvelles syntaxes JS et comment elles seront compilées, vous pouvez vérifier babel . Par exemple, copier votre code dans babel et sélectionner le préréglage es2015 donnera une sortie comme celle-ci
la source
Pensez-y comme ceci, chaque fois que vous voyez une flèche, vous la remplacez par
function
.function parameters
sont définis avant la flèche.Donc dans votre exemple:
puis ensemble:
De la documentation :
la source
this
.Bref et simple 🎈
C'est une fonction qui retourne une autre fonction écrite de façon courte.
Pourquoi les gens le font ❓
Avez-vous dû faire face lorsque vous avez besoin d'écrire une fonction qui peut être personnalisée? Ou vous devez écrire une fonction de rappel qui a des paramètres fixes (arguments), mais vous devez passer plus de variables à la fonction mais en évitant les variables globales? Si vous répondez « oui », c'est la façon de le faire.
Par exemple, nous avons un
button
rappel avec onClick. Et nous devons passerid
à la fonction, maisonClick
n'accepte qu'un seul paramètreevent
, nous ne pouvons pas passer de paramètres supplémentaires comme ceci:Ça ne marchera pas!
Par conséquent, nous créons une fonction qui retournera une autre fonction avec sa propre portée de variables sans aucune variable globale, car les variables globales sont mauvaises 😈.
Ci-dessous la fonction
handleClick(props.id)}
sera appelée et renverra une fonction et elle auraid
dans sa portée! Peu importe combien de fois il sera pressé, les identifiants n'affecteront ni ne changeront les uns les autres, ils sont totalement isolés.la source
L'exemple de votre question est celui
curried function
qui utilisearrow function
et a unimplicit return
pour le premier argument.La fonction flèche lie lexicalement ce qui signifie qu'ils n'ont pas leur propre
this
argument mais prennent lathis
valeur de la portée englobanteUn équivalent du code ci-dessus serait
Une autre chose à noter à propos de votre exemple est que définir
handleChange
comme une constante ou une fonction. Vous l'utilisez probablement dans le cadre d'une méthode de classe et il utilise unclass fields syntax
donc au lieu de lier directement la fonction externe, vous la lieriez dans le constructeur de classe
Une autre chose à noter dans l'exemple est la différence entre le retour implicite et explicite.
Ci-dessus est un exemple de retour implicite ie. il prend le champ de valeur comme argument et renvoie le résultat
field*2
qui spécifie explicitement la fonction à renvoyerPour un retour explicite, vous diriez explicitement à la méthode de renvoyer la valeur
Une autre chose à noter sur les fonctions fléchées est qu'elles n'ont pas les leurs,
arguments
mais héritent également de la portée des parents.Par exemple, si vous définissez simplement une fonction de flèche comme
Comme alternative, les fonctions fléchées fournissent les paramètres de repos que vous pouvez utiliser
la source
Ce n'est peut-être pas totalement lié, mais puisque la question mentionnée réagit utilise le cas (et je continue de me heurter à ce fil SO): Il y a un aspect important de la fonction de double flèche qui n'est pas explicitement mentionné ici. Seule la `` première '' flèche (fonction) est nommée (et donc `` reconnaissable '' par l'exécution), les flèches suivantes sont anonymes et du point de vue React comptent comme un `` nouvel '' objet sur chaque rendu.
Ainsi, la fonction de double flèche entraînera le rendu permanent de tout composant PureComponent.
Exemple
Vous avez un composant parent avec un gestionnaire de modifications comme:
et avec un rendu comme:
{ tasks.map(task => <MyTask handleChange={this.handleChange(task)}/> }
handleChange puis utilisé sur une entrée ou un clic. Et tout cela fonctionne et est très joli. MAIS cela signifie que tout changement qui entraînera le rendu du parent (comme un changement d'état complètement indépendant) restituera également TOUS vos MyTask également, même s'il s'agit de PureComponents.
Cela peut être atténué de nombreuses façons, comme passer la flèche `` la plus à l'extérieur '' et l'objet avec lequel vous l'alimenter ou écrire une fonction shouldUpdate personnalisée ou revenir à des bases telles que l'écriture de fonctions nommées (et la liaison manuelle de ceci ...)
la source