Demistyfikujące hooki React — useCallback
Rozpoczęcie pracy
Jeśli chcesz podążać za lokalnym środowiskiem IDE, możesz znaleźć repozytorium GitHub tutaj .
clonecd clientnpm inpm start
Równość referencyjna jest fundamentalną koncepcją zarówno w JavaScript, jak iw informatyce jako całości. Zacznijmy więc od zademonstrowania tego w działaniu.
Osadziłem zrzuty ekranu w całym artykule, aby ułatwić korzystanie z urządzenia mobilnego. Jeśli jesteś na komputerze i sklonowałeś go, uruchom, referentialEquality.jsaby obserwować dane wyjściowe lub po prostu pobaw się fragmentem kodu JSFiddle osadzonym poniżej.
Podczas oceniania, czy integer 1jest ściśle równe integer 1, konsola drukuje true. Dzieje się tak, ponieważ, no cóż… the integer 1 jest ściśle równe integer 1.
Widzimy ten sam wynik podczas oceny dwóch łańcuchów.
Oczywiście będzie tak zawsze w przypadku dwóch pierwotnych typów danych o tej samej wartości.
A co ze strukturami danych? Na przykład dwa literały obiektowe z tymi samymi parami klucz/wartość? A co z pustymi literałami obiektowymi?
Dlaczego ten wydruk false? Porównując, czy te dwa literały obiektowe są ściśle równe, JavaScript używa ich odpowiednich adresów pamięci .
Innymi słowy, te dwa obiekty mogą zawierać te same wartości , ale nie odwołują się do tego samego obiektu . Wyglądają tak samo, ale zajmują dwa różne miejsca w pamięci .
To samo dotyczy tego, czy porównujesz dwa literały obiektowe, dwa literały tablicowe czy dwie funkcje!
Aby to dokładniej zademonstrować, zdefiniujemy funkcję func, która zwraca anonimową funkcję, która z kolei zwraca coś innego ( np. element JSX ).
Następnie przypiszemy dwie różne funkcje firstRenderi secondRender, równe wartości zwróconej przez func.
Pomyśl o funcswoim komponencie funkcjonalnym React, podczas gdy firstRenderjest funkcją wewnątrz niego na pierwszym renderowaniu i secondRenderjest funkcją wewnątrz niego na drugim renderowaniu.
Mimo że firstRenderi secondRenderzwracają tę samą wartość i są przypisane z tej samej definicji, nie mają równości referencyjnej . W rezultacie za każdym razem, gdy komponent jest renderowany, ponownie definiuje tę funkcję.
Niestety, w JavaScript nie jest łatwo wydrukować te adresy pamięci, tak jak w Pythonie, ale nieco bardziej dogłębne wyjaśnienie stosunku referencji do wartości można znaleźć w tym artykule z freeCodeCamp.
Ten temat może stać się gęsty i nie musisz dziś prowadzić zajęć na ten temat. Więc na razie pamiętaj:
- prymitywny typ danych
===prymitywny typ danych - struktura danych
!==struktura danych.
Kod startowy
Po uruchomieniu naszej aplikacji otwórz BookDetails.jsxkomponent i ponownie zapisz. Pierwszą rzeczą, którą możemy zauważyć na naszym serwerze deweloperskim React, jest to, WARNINGco często jest ignorowane przez młodych programistów. Kiedy trafisz na siłę roboczą i zaczniesz pisać kod do produkcji, twoje lintery będą jeszcze bardziej rygorystyczne niż to, co jest wbudowane w create-react-app. WARNINGSzmieni się na ERRORS, a niektóre linters nie pozwolą ci nacisnąć, zanim zajmiesz się tymi ERRORS.
Więc zamiast go ignorować, zastanówmy się, jak go leczyć.
UWAGA: może być konieczne ponowne zapisanie, BookDetails.jsxaby to utworzyćWARNING
Jeśli zagłębimy się w React Docs , możemy rozszyfrować na wpół mylące proponowane rozwiązania tego problemu WARNINGw następujący sposób:
1. Dołącz definicję funkcji do pliku useEffect.
- Nie możemy wywołać tej funkcji gdzie indziej, chyba że ponownie ją zdefiniujemy.
- Spowoduje to wyzwolenie
useEffectkażdej zmiany stanu lub rekwizytów, czasami powodując nieskończone ponowne renderowanie. A w naszym przypadku, ponieważ wywołujemy naszą funkcję ustawiającą stan po wywołaniu interfejsu API, może to spowodować przeciążenie naszego interfejsu API nieskończoną liczbą żądań punktów końcowych.
- Funkcja nie zostanie wywołana.
- Gdy komponent renderuje się po raz pierwszy, zdefiniuje naszą funkcję, która uruchomi
useEffect, co spowoduje ponowne wyrenderowanie komponentu, co ponownie zdefiniuje funkcję, która uruchomi ,useEffectco spowoduje ponowne wyrenderowanie komponentu, co ponownie zdefiniuje funkcję…
Najprostszym i preferowanym rozwiązaniem byłoby „dołączenie go”, czyli przeniesienie getBookDetailsdefinicji funkcji do pliku useEffect. Jest to zgodne z zasadą programowania obiektowego znaną jako enkapsulacja .
Ale powiedzmy, że wiemy, że musimy wywołać tę funkcję gdzie indziej. Czy powinniśmy to przedefiniować później? To nie jest bardzo SUCHE z naszej strony.
Zmieńmy naszą tablicę zależności, aby zawierała nasze odwołanie do funkcji. Twój useEffectpowinien teraz wyglądać tak.
I pozostaje getBookDetailszdefiniowany powyżej .useEffect
Teraz mamy noweWARNING
Wprowadź hak useCallback
Krótko mówiąc, useCallbackhak umożliwia buforowanie lub „zapamiętywanie” funkcji między ponownymi renderowaniami komponentu. Wykonuje podobne zadanie do useMemo, którego niuanse omówimy w innym artykule.
Jeśli interesują Cię szczegółowe informacje na ten temat, możesz przeczytać więcej w dokumentacji React .
Zwróć uwagę na ich ostrzeżenie:
Powinieneś polegać tylko useCallbackna optymalizacji wydajności. Jeśli Twój kod nie działa bez niego, znajdź podstawowy problem i napraw go najpierw. Następnie możesz dodać useCallback, aby poprawić wydajność.
useCallbackSkładnia
useCallbackSkładnia 's jest bardzo podobna do useEffectskładni '', którą już znamy. Spójrz na szkielety każdego z nich.
Niewielka różnica polega na tym useEffect, że w przypadku , mówimy funkcji anonimowej, aby wykonała naszą funkcję, podczas gdy w przypadku useCallback, przypisujemy wartość zwracaną do odwołania, które ma zostać wywołane gdzie indziej.
Za pomocą useCallback
Najpierw zaimportujemy useCallbackz 'react'. Zamiast dodawać nowy wiersz, najlepiej zdekonstruować go wraz z innymi naszymi importami.
Teraz możemy przypisać getBookDetailswartość zwróconą z useCallbackwywołania funkcji.
Następnie dodajemy całą składnię dla useCallback. Zapamiętaj swoją tablicę zależności!
W naszym przykładzie potrzebujemy asyncprzed naszymi parametrami.
Na koniec dodajemy logikę naszej funkcji do bloku kodu.
Gdy zapiszemy, dostajemy… kolejną WARNING.
Dlaczego nasza tablica zależności powinna śledzić idzmienną?
Przemyślmy to.
- Jeśli wartość
idzmiangetBookDetailsmusi trafić w inny punkt końcowy, więc React powinien go przedefiniować. DefinicjagetBookDetailsdosłownie zależy od wartościid.
I wreszcie, to jest to! Widzimy kolor zielony na naszym serwerze deweloperskim React. Szczęśliwy Linter to szczęśliwy Senior Developer. A szczęśliwy Senior Developer to szczęśliwy Ty!
Zawsze szukam nowych przyjaciół i kolegów. Jeśli ten artykuł okazał się pomocny i chcesz się połączyć, możesz mnie znaleźć w dowolnym z moich domów w sieci.
GitHub | Twitter | LinkedIn | Stronie internetowej
Zasoby
- Równość referencyjna
- Pierwotne typy danych JavaScript a struktury danych
- Kapsułkowanie
useCallback- Reaguj Dokumenty

![Czym w ogóle jest lista połączona? [Część 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































