Techniki Zaawansowane
6 godz. 6 min · ReactJS · Full-stack i Programowanie
Adam RomanskiFrontend developer & YouTube CreatorJeden z pierwszych i najbardziej popularnych wzorców w React, który przez lata był traktowany jako najlepszy sposób na wydzielanie logiki z komponentów i współdzielenie jej w wielu miejscach aplikacji. W kursie na przykładzie dowiesz się w jaki sposób można wykorzystać HOC, a także jak łączyć je ze sobą tworząc bardziej zaawansowane struktury.
Obecnie Render Props jest jedną z najczęściej wykorzystywanych praktyk pozwalającą, podobnie jak HOC, na tworzenie abstrakcji, z których możemy czerpać dane lub zachowania potrzebne w naszych komponentach. Na pierwszy rzut oka Render Props mogą przerażać, ale spokojnie – zaczniemy od prostego przykładu, który pozwoli Ci zrozumieć, że nie ma się czego bać.
Hooks to temat niezwykle ciekawy i populary, ale rzadko poruszany w sposób bardziej zaawansowany. W tym kursie dowiesz się nie tylko jak używać takich hooków jak useState, useReducer, useEffect, useContext czy useRef, ale też jak napisać swoje własne hooki, które niesamowicie uprzyjemnią pracę z Reactem.
Compound Components to prawdziwa "ciężka artyleria" Reacta – stosowana w zadaniach wymagających sporej złożoności. Ewoluowała przez lata i kiedyś zawsze spotykana była w formie klas, natomiast w tym kursie proponujemy nieco lżejsze podejście. Dowiesz się jak wykorzystując hooki możesz stworzyć Compound Component wyłącznie przy użyciu komponentów funkcyjnych.
Testy to hasło, które potrafi wzbudzić lęk u osób uczących się Reacta, lub jakiejkolwiek innej technologii. Rzadko kto jednak mówi to głośno – testy są przyjemne! Wystarczy tylko zrozumieć w jaki sposób środowisko testowe działa i jakimi rządzi się zasadami. Przerobimy to wszystko wspólnie, a na koniec kursu przekonasz się, że to faktycznie ciekawe i przyjemne zagadnienie.
W kursie przygotowana jest też garść dobrych praktyk, które pozwolą Ci spojrzeć krytycznie na niektóre fragmenty kodu i ulepszać je w taki sposób, aby stanowiąc część większej całości miały więcej sensu i wdzięku. Dowiesz się czym jest Single Responsibility Principle, jak wydzielać odpowiednio logikę z komponentów i paru innych ciekawych wskazówek.
Ten kurs został stworzony z myślą o programistach swobodnie poruszających się po podstawach i nieco bardziej skomplikowanych partiach Reacta, ale nadal czujących, że brakuje im czegoś, aby wynieść swoje aplikacje na jeszcze wyższy poziom. Rzeczy związane z zaawansowanym JavaScriptem będziemy tu wykorzystywać intuicyjnie, bez zbędnego tłumaczenia, dlatego zanim przystąpisz do tego kursu, upewnij się, że treści React od Podstaw oraz React w Praktyce są dla Ciebie jasne i zrozumiałe.
16.8.x
Cześć kontynuujemy zabawę z naszymi inputem i pewnie
zauważyłeś zauważyłaś że do tej pory ani razu nie wykorzystaliśmy naszego
komponentu w aplikacji nie sprawdziliśmy czy on działa i to jest właśnie fajne w testowaniu
zwłaszcza z takim podejściem test driven development że tak naprawdę pisząc testy i
naprawiając je podczas pisania właściwego komponentu mamy właściwie
pewność że on będzie działał nie musimy za każdym razem wchodzić do przeglądarki i sprawdzać czy na przykład
nie możemy podawać cyfr zaraz to zresztą sprawdzimy na własne
oczy ale chciałem najpierw tutaj podkreślić to że testy pozwalają na
dowożenie tak naprawdę naszego kodu z pewnością że on będzie działał
oczywiście później są jeszcze dalsze etapy są testy end to end jest quality assurance
i wszystko to co sprawia że na pewno wiemy że nasz komponent działa czy
też właściwie cała aplikacja działa jak potrzeba natomiast fajne jest to że pisząc
testy mamy naprawdę sporą pewność że wszystko będzie git więc jak sobie zerkniemy
na nasz komponent to widzimy że w naszych prop-types'ach brakuje
tutaj dwóch propsów które podajemy więc teraz je po prostu dopiszemy żeby mieć z tym spokój name
będzie wymagane
i podobnie label to będą dwa propsy które są wymagane
a teraz przejdźmy sobie do naszego widoku app js zaimportujmy
sobie tutaj nasz input mam
tutaj odpaloną oczywiście aplikacje na localhoście i widzimy że nasz input
jest i przede wszystkim nie podawałem żadnego propsa do niego
nawet placeholdera a więc placeholder jest domyślny i to właśnie
sprawdzał jeden z naszych testów displays placeholder tutaj
wszystko to było ogarnięte dodatkowo jak odpalimy konsolę to widzimy
że nie mamy podanych propsów name i label no i oczywiście
dla użytkownika to nie jest super ważna informacja ale deweloper na etapie developmentu
to na pewno będzie widział w konsoli że tych propsów nie ma podanych więc teraz je
sobie dodamy po
kliknięciu na label oczywiście fokusuje nam się nasz input i
teraz spróbujmy tutaj cokolwiek wpisać i teraz nacisnę
raz dwa trzy i to faktycznie działa czyli nie mogę
wpisywać cyfr mogę wpisywać tylko litery więc
nasz input działa tak jak należy a teraz już po tym
krótkim podsumowaniem wrócimy sobie do naszego testu i wpiszemy kolejny
scenariusz który zastąpi nam poniekąd to co wpisaliśmy ostatnio czyli it prevents
from passing numbers teraz sobie zrobimy walidacje
która wyświetla po prostu błąd w momencie kiedy jakiś właśnie nieprawidłowy
znak został podany więc pierwsze co możemy zrobić to wrócić sobie do naszych testów tutaj
widzimy że po wpisaniu prop-types'ów tutaj w tym miejscu dostajemy
błąd że wcześniej w naszych komponentach
nie podawaliśmy żadnych propsów więc teraz je
podamy tak żeby w każdym miejscu były chociaż te wymagane możemy
to sobie po prostu skopiować tak żeby on się odczepił czy
jeszcze w którymś miejscu jeszcze tutaj nie mamy tak
naprawdę to name tutaj nie ma żadnego znaczenia moglibyśmy tutaj wpisywać tutaj na przykład h albo
x cokolwiek ale żeby było ładnie no to już tak
zrobiłem pamiętaj że testom nie zależy na tym żeby to
była jakaś konkretna wartość to może być naprawdę cokolwiek więc warto
mieć to na uwadze ale mimo wszystko ten test zawsze będzie czytał człowiek więc ja
staram się jakby imitować wygląd tego komponentu taki jaki by był
właśnie w prawdziwej aplikacji nie jestem w stanie
określić czy jest to najlepsza praktyka na świecie ale dla mnie jest
ta na pewno przyjemniejsze żeby w ten sposób to pisać możemy sobie usunąć ten test on
już jest nam niepotrzebny i razem z tym testem możemy usunąć logikę która
zapobiegała nam dodawaniu cyfr do naszego inputa
teraz z powrotem będzie można to robić poza tym
nic nie zmieniamy ta metoda pozostaje ona nadal będzie nam potrzebne a
my po prostu powiemy displays error
when digits are passed i
teraz oczywiście po raz kolejny wyciągamy
sobie z metody render get by label text pamiętamy
już o tym że musimy podać wszystkie propsy i teraz
najpierw stwórzmy sobie nasz input który będzie właśnie wykorzystywał
get by label text label tutaj mamy name
stosuje ten regex
zawsze dlatego że jest to po prostu bezpieczniejsza jakby na przykład gdzieś się pomylił
i wpisał tak to i tak złapie ten element więc nie muszę się o to martwić jest
on tutaj gdzieś kryty w ten sposób po tym jak złapałem sobie nasz input mogę wykorzystać fire
event change i podam
tutaj roman 1 i teraz będziemy
mieć jeszcze jeden element który będzie właśnie tekstem walidacyjnym który powiedzmy
że za każdym razem w naszej aplikacji będzie zawierał słowo error i
po właśnie po tym słowie będziemy go łapać więc możemy sobie wziąć tutaj kolejną
metodę get by text stworzymy sobie łapacz nie
wiem chyba mogę to tak nazwać mamy tutaj łapacz get by text
który będzie łapał nam cokolwiek co zawiera słowo error nieważne
czy ma wielką literą czy małą dostajemy oczywiście błąd że nie
ma czegoś takiego w naszym teście ale to jeszcze nic bo
dodatkowo jeszcze zepsujemy go podwójnie dodając tutaj expect
error to be in the document i
w ten sposób cały nasz test po prostu nie przechodzi w tym momencie
dodamy sobie tutaj p to napiszemy error i
nasz test zaczął przechodzić ponieważ pojawił się element który zawiera
słowo error problem jest tylko taki że my nie chcemy żeby
on się pojawiał zawsze jeśli tutaj zrobimy coś takiego to
ten test też nam przychodzi więc musimy ten
test zepsuć jeszcze raz ponieważ tak naprawdę jeśli chcielibyśmy
sprawdzić czy ten warunek tutaj z tego testu jest spełniony to najpierw powinniśmy
założyć że ten element który testujemy jest niewidoczny a dopiero po
stworzeniu tego eventu zawiera jakąś cyfrę on staje się widoczny więc
jak tę metodę to be in the document zrobić tak
żeby ona była zaprzeczeniem na szczęście jest przychodzi nam tutaj z pomocą i mamy coś
takiego jak zaprzeczenie po prostu not jeśli wpisujemy między
kropkami not łącząc jakby te wszystkie metody ze sobą to
nasz test uwaga failuje ponieważ ten element pojawił się w naszym
dokumencie jeśli teraz zrobimy coś takiego że
dodamy sobie tutaj kolejny use state nazwiemy
go is error visible i set error
visibility tutaj
oczywiście damy false i teraz warunkowo
renderując nasz komponent w
taki sposób sprawimy że on nie będzie widoczny
dopóki nie ustawimy że ma być widoczny okej nasz test
się zepsuł teraz z innego powodu ponieważ znowu nie widzi tego elementu teraz
co możemy zrobić a problem jest
tylko taki że ten błąd będzie wyskakiwał ponieważ tego consta
zapisujemy wcześniej niż ten element się pojawia w naszym teście to zróbmy tak wywalmy
nie będziemy tego error'a w ten sposób brać on będzie po prostu wpisywany bezpośrednio
tutaj w to miejsce więc
teraz jakby duplikując te rzeczy tutaj
wpisując właśnie ten error psujemy nasz test
w ten sposób że najpierw podajemy prawidłowego stringa i
mówimy że ten error on ma się nie znajdować naszym dokumencie a
po wpisaniu cyfr ma się pojawić problem jest tylko taki
że wykorzystując tutaj tę metodę tak naprawdę próbujemy wyłapać
coś co nie istnieje tego nie ma ponieważ on jest po prostu tutaj
ukryty a właściwie jest niewyrenderowany i to jest właśnie cały
problem bo jakby był ukryty na przykład klasą to wtedy on by istniał tylko byłby
niewidoczny to był niewielki problem natomiast tutaj musimy podejść do tego problemu
w trochę inny sposób musimy trochę odwrócić naszą logikę
zamiast używać get by text musimy wyciągnąć
sobie container który zawiera wszystko co zawiera nasz komponent
czyli wszystko to i teraz z tego kontenera
w jednym i drugim miejscu możemy użyć sobie metody
to have text content tutaj content
tutaj mamy regex'a którego możemy użyć i wtedy on po prostu sobie znajdzie
czy nasz kontener czyli tutaj w tym miejscu czy w ogóle pojawia nam się jakiś error
a z racji że tylko ten element ma słowo error to będzie to idealny
dla naszej sytuacji więc tutaj to zastąpimy to have
to have text content
podkreślam to jest metoda jest dom a nie
react testing library i tutaj w tym miejscu wpiszemy
po prostu regex'a error case
insensitive ponieważ to jest jakby detal implementacyjny
czy to będzie wielką czy małą literą i teraz oczywiście z racji
że default'owo mamy ustawione jako false to nasz element się nie wyświetla więc ten test
nadal failuje i teraz musimy sobie napisać w końcu metodę która nam to
naprawi więc wewnątrz handle change musimy sobie sprawdzić dwie
rzeczy wpiszemy sobie tutaj tego regex'a i
teraz jeśli nasz
input zawiera jakieś cyfry to
ustawiamy set error visibility na true w
przeciwnym wypadku ustawiamy na false ten
blok jest istotny z tego względu że musi być to else dlatego że nawet
jeśli byśmy ustawili to na tył ale na przykład usunęlibyśmy nasze
cyfry no to wtedy musi się z powrotem ustawić na false i
tutaj nadal mamy błąd ale jestem jakiś dziwny bo to powinno działać sprawdźmy
czy tutaj wszystko a okej dobra target
roman uwaga target target i
teraz nasz test przechodzi co więcej jeśli teraz sobie znowu odpalimy
nasz event i usuniemy to to teraz powinno znowu
sfailować tak failuje
ponieważ oczekujemy że ten error nadal będzie się pojawiał tymczasem usunęliśmy tutaj
cyfry więc one ten error znika więc teraz znowu powinniśmy
zrobić nad wtedy testujemy czy on się
czy jest jakby nie nieobecny później
czy jest obecny i na końcu czy jest nieobecny tak naprawdę możemy
zrobić jeszcze jdną rzecz po prostu to pierwsze usunąć i wtedy mówimy czy on jest
niewidoczny za pierwszym razem po wpisaniu czegokolwiek
czy on się pojawia i czy po usunięciu cyfr on się też on też znika
i tym sposobem nasz test działa wszystko mamy gotowe
w następnej lekcji zajmiemy się optymalizacją tego jak wygląda
nasz test ponieważ jak widzisz mam tutaj bardzo dużo powtarzanego kodu i to nie jest do końca fajne
ale zaraz sobie z tym poradzimy