Czytam sporo react
kodu i widzę takie rzeczy, których nie rozumiem:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
Czytam sporo react
kodu i widzę takie rzeczy, których nie rozumiem:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
Odpowiedzi:
To jest funkcja curry
Najpierw sprawdź tę funkcję za pomocą dwóch parametrów…
Tutaj znów jest w curry…
Oto ten sam 1 kod bez funkcji strzałek…
Skupić się na
return
Może to pomóc zobrazować to w inny sposób. Wiemy, że funkcje strzałek działają w ten sposób - zwróćmy szczególną uwagę na wartość zwracaną .
Nasza
add
funkcja zwraca więc funkcję - możemy użyć nawiasów dla większej przejrzystości. Pogrubiony tekst jest zwracana wartość naszej funkcjiadd
Innymi słowy,
add
pewna liczba zwraca funkcjęWywoływanie funkcji curry
Aby więc skorzystać z naszej funkcji curry, musimy ją nazwać nieco inaczej…
Jest tak, ponieważ pierwsze (zewnętrzne) wywołanie funkcji zwraca drugą (wewnętrzną) funkcję. Dopiero po wywołaniu drugiej funkcji uzyskujemy wynik. Jest to bardziej widoczne, jeśli rozdzielimy połączenia na dwóch liniach…
Zastosowanie naszego nowego zrozumienia do twojego kodu
OK, teraz, gdy rozumiemy, jak to działa, spójrzmy na twój kod
Zaczniemy od przedstawienia go bez użycia funkcji strzałek…
Ponieważ jednak funkcje strzałek wiążą się leksykalnie
this
, w rzeczywistości wyglądałoby to mniej więcej tak…Może teraz możemy zobaczyć, co to robi wyraźniej.
handleChange
Funkcji tworzy funkcję określonafield
. Jest to przydatna technika React, ponieważ musisz skonfigurować własne detektory na każdym wejściu, aby zaktualizować stan aplikacji. Korzystając z tejhandleChange
funkcji, możemy wyeliminować cały zduplikowany kod, który spowodowałby skonfigurowaniechange
detektorów dla każdego pola. Fajne!1 Tutaj nie musiałem wiązać leksykalnie,
this
ponieważadd
funkcja oryginalna nie używa żadnego kontekstu, więc nie jest ważne, aby zachować ją w tym przypadku.Jeszcze więcej strzał
W razie potrzeby można sekwencjonować więcej niż dwie funkcje strzałek -
Funkcje curry potrafią zaskakiwać. Poniżej widzimy
$
definicję funkcji curry z dwoma parametrami, ale w witrynie wywoławczej wydaje się, że możemy podać dowolną liczbę argumentów. Curry to abstrakcja arity -Częściowe zastosowanie
Częściowe zastosowanie jest powiązaną koncepcją. Pozwala nam częściowo zastosować funkcje podobne do curry, z tą różnicą, że funkcja nie musi być zdefiniowana w formie curry -
Oto działające demo, z
partial
którym możesz grać we własnej przeglądarce -źródło
$
został użyty do demonstracji koncepcji, ale możesz nazwać ją, jak chcesz. Przypadkowo jednak zupełnie niepowiązane,$
nie zostały wykorzystane w popularnych bibliotek takich jak jQuery, gdzie$
jest rodzajem globalnego punktu wejścia do całej biblioteki funkcji. Myślę, że był używany także w innych. Kolejnym, który zobaczysz, jest_
spopularyzowany w bibliotekach takich jak podkreślenie i lodash. Żaden symbol nie ma większego znaczenia niż inny; Państwo przypisać znaczenie dla Twojego programu. To jest po prostu poprawny JavaScript: D$
, patrząc na to, jak jest używany. Jeśli pytasz o samą implementację,$
to funkcja, która otrzymuje wartośćx
i zwraca nową funkcjęk => ...
. Patrząc na treść zwróconej funkcji, widzimy,k (x)
więc wiemy, żek
musi to być również funkcja, i cokolwiek wynik tegok (x)
zostanie przywrócone$ (...)
, co, jak wiemy, zwraca innąk => ...
, i tak dalej ... Jeśli nadal jesteś utknąć, daj mi znać.abc(1,2,3)
jest mniej niż idealny niżabc(1)(2)(3)
. Trudniej jest zrozumieć logikę kodu i trudniej odczytać funkcję abc, a trudniej odczytać wywołanie funkcji. Wcześniej musieliście tylko wiedzieć, co robi abc, teraz nie jesteście pewni, jakie funkcje bezimienne zwraca abc, i to dwukrotnie.Zrozumienie dostępnych składni funkcji strzałek pozwoli ci zrozumieć, jakie zachowania wprowadzają, gdy są „powiązane”, jak w podanych przez ciebie przykładach.
Gdy funkcja strzałki jest zapisywana bez nawiasów blokowych, z wieloma parametrami lub bez nich, wyrażenie, które stanowi ciało funkcji, jest domyślnie zwracane. W twoim przykładzie to wyrażenie jest kolejną funkcją strzałki.
Kolejną zaletą pisania anonimowych funkcji przy użyciu składni strzałki jest to, że są one powiązane leksykalnie z zakresem, w którym są zdefiniowane. Z „Funkcje strzałek” w MDN :
Jest to szczególnie istotne w twoim przykładzie, biorąc pod uwagę, że pochodzi z Reagujepodanie. Jak wskazał @naomik, w React często uzyskuje się dostęp do funkcji członka komponentu za pomocą
this
. Na przykład:źródło
Ogólna wskazówka: jeśli pomyli Cię jakaś nowa składnia JS i sposób jej kompilacji, możesz sprawdzić babel . Na przykład skopiowanie kodu w Babel i wybranie ustawienia wstępnego es2015 da takie wyjście
źródło
Pomyśl o tym w ten sposób, za każdym razem, gdy zobaczysz strzałkę, zamień ją na
function
.function parameters
są zdefiniowane przed strzałką.W twoim przykładzie:
a następnie razem:
Z dokumentów :
źródło
this
.Krótkie i proste 🎈
Jest to funkcja, która zwraca inną funkcję napisaną w skrócie.
Dlaczego ludzie to robią ❓
Czy napotkałeś, kiedy musisz napisać funkcję, którą można dostosować? A może musisz napisać funkcję zwrotną, która ma stałe parametry (argumenty), ale musisz przekazać więcej zmiennych do funkcji, ale unikać zmiennych globalnych? Jeśli Twoja odpowiedź brzmi „ tak ”, to po prostu jak to zrobić.
Na przykład mamy
button
wywołanie zwrotne onClick. I musimy przejśćid
do funkcji, aleonClick
akceptuje tylko jeden parametrevent
, nie możemy przekazać dodatkowych parametrów w ten sposób:To nie zadziała!
Dlatego tworzymy funkcję, która zwróci inną funkcję z własnym zakresem zmiennych bez zmiennych globalnych, ponieważ zmienne globalne są złe 😈.
Poniżej funkcja
handleClick(props.id)}
zostanie wywołana i zwróci funkcję, która będzie miałaid
swój zasięg! Bez względu na to, ile razy zostanie wciśnięty, identyfikatory nie będą się zmieniać ani zmieniać, są całkowicie odizolowane.źródło
Przykładem twojego pytania jest przykład,
curried function
który korzysta zarrow function
i maimplicit return
za pierwszy argument.Funkcja strzałki wiąże to leksykalnie, tzn. Nie ma własnego
this
argumentu, ale bierzethis
wartość z otaczającego zakresuOdpowiednikiem powyższego kodu byłoby
Jeszcze jedną rzeczą wartą odnotowania w twoim przykładzie jest to, że definiują
handleChange
jako const lub funkcję. Prawdopodobnie używasz go jako części metody klasowej i używa onclass fields syntax
więc zamiast bezpośredniego wiązania zewnętrznej funkcji, powiążemy ją w konstruktorze klasy
Inną rzeczą, na którą należy zwrócić uwagę w tym przykładzie, jest różnica między zwrotem niejawnym i jawnym.
Powyżej znajduje się przykład niejawnego zwrotu, tj. przyjmuje pole wartości jako argument i zwraca wynik
field*2
który wyraźnie określa funkcję do zwróceniaAby uzyskać wyraźny zwrot, należy wyraźnie wskazać metodę zwrotu wartości
Inną rzeczą, na którą należy zwrócić uwagę w przypadku funkcji strzałek, jest to, że nie mają one własnych,
arguments
ale dziedziczą to również z zakresu rodziców.Na przykład, jeśli zdefiniujesz funkcję strzałki, np
Jako alternatywne funkcje strzałek podaj pozostałe parametry, których możesz użyć
źródło
Może nie jest to całkowicie powiązane, ale ponieważ wspomniane pytanie reaguje na przypadki (i ciągle wpadam na ten wątek SO): Istnieje jeden ważny aspekt funkcji podwójnej strzałki, który nie jest tutaj wyraźnie wymieniony. Tylko pierwsza „strzałka” (funkcja) zostaje nazwana (a zatem „rozróżnialna” w czasie wykonywania), kolejne strzałki są anonimowe iz punktu widzenia React są liczone jako „nowy” obiekt na każdym renderowaniu.
W ten sposób funkcja podwójnej strzałki spowoduje, że dowolny PureComponent będzie się ciągle powtarzał.
Przykład
Masz komponent nadrzędny z modułem obsługi zmian, takim jak:
oraz z renderowaniem takim jak:
{ tasks.map(task => <MyTask handleChange={this.handleChange(task)}/> }
handleChange następnie używany na wejściu lub kliknięciu. I to wszystko działa i wygląda bardzo ładnie. ALE oznacza to, że każda zmiana, która spowoduje, że rodzic zrenderuje (jak zupełnie niezwiązana zmiana stanu), również zrenderuje CAŁĄ twoją MyTask, nawet jeśli są PureComponents.
Można to złagodzić na wiele sposobów, takich jak przekazywanie strzałki „najbardziej wysuniętej” i obiektu, którym chcesz ją nakarmić, lub pisanie niestandardowej funkcji powinno aktualizować lub powrót do podstaw, takich jak pisanie nazwanych funkcji (i wiązanie jej ręcznie ...)
źródło