w Praktyce
6 godz. 51 min · ReactJS · Full-stack i Programowanie
Adam RomanskiFrontend developer & YouTube CreatorNarzędzia typu ESlint, Prettier, Husky czy lint-staged niezmiernie pomagają nam w pracy. Problem jednak polega na tym, że ich konfiguracja bywa kłopotliwa. W tym kursie dowiesz się, jak poprawnie skonfigurować te narzędzia, tak, aby nie wchodziły ze sobą w konflikty i pomagały nam pisać lepszy kod.
Brzmi jak zły pomysł? Wcale nie! CSS in JS to rewolucyjne podejście, które pozwala nam tworzyć style bezpośrednio w komponentach. Dzięki bibliotece Styled Components możesz wpływać na ich stan, wygląd i wiele innych rzeczy. To niezwykłe narzędzie, wprowadzające powiew świeżości dla ludzi zmęczonych czystym CSS.
Dokumentowanie wyglądu i zachowania naszych komponentów bywa kłopotliwe. Jeśli jednak użyjemy odpowiednich narzędzi, staje się banalne! Storybook w połączeniu z podejściem atomic design pozwoli nam na stworzenie świetnie udokumentowanych komponentów.
React w Praktyce nie byłby... praktyczny, gdyby nie pokazanie tego, w jaki sposób rozwiązuje się problemy z layoutem aplikacji. Sidebary, szablony, powtarzalne komponenty – to wszystko poznasz w tym kursie.
Tworzenie store, czyli warstwy z danymi w naszej aplikacji dla wielu bywa wyzwaniem dość trudnym. Wynika to często z tego, że przykłady Reduxa bywają niepraktyczne. W tym kursie dowiesz się, w jaki sposób działa Redux – zaczniemy od podstaw, a skończymy na rozbudowanej strukturze danych. Dzięki temu zobaczysz, że nie taki Redux straszny jak go malują.
Aplikacja frontendowa bez backendu może istnieć, choć jej możliwości będą zdecydowanie ograniczone. A już na pewno będzie ona miała kiepską pamięć. Dlatego w tym kursie stworzymy lokalną wersję backendu połączoną z MongoDB na mLab. W ten sposób będziemy mogli dłużej przechowywać dane zapisane w naszych komponentach.
O testach można mówić wiele. To niezwykle rozległy temat, dlatego zanim zaczniesz je pisać na poważnie, chcę Ci pokazać jak możesz poćwiczyć podstawowe rzeczy. Poznasz narzędzie JEST, które odpowiada za uruchamianie testów, oraz wprowadzę Cię do react-testing-library, jednej z najpopularniejszych bibliotek do testowania aplikacji reactowych.
Ten kurs przeznaczony jest dla osób, które lada dzień będą aplikować na stanowiska juniorskie jako React developer. Zawarłem w nim wiele aspektów pracy z React, które zdarzają się w prawdziwej pracy. Ponadto skorzystać mogą z niego osoby, które znają inny framework JS i chcą nauczyć się Reacta, jednak kursy od podstaw są dla nich zbyt proste.
16.8.x
Cześć, w ostatniej lekcje udało nam się stworzyć mechanizm, który pozwala nam na usuwanie
naszych notatek ze store'a, a teraz przyszedł czas na dalszy
rozwój naszej aplikacji, ale zanim zaczniemy sobie dodawać nowe notatki
to jest jedna bardzo ważna rzecz związana z naszą aplikacją,
która narażają na okropne problemy ze stabilnością. Wynika
to z faktu, że podajemy w bardzo wielu miejscach prop card type, page type
i tak dalej. One są zależne od siebie bardzo duża
część aplikacji polega właśnie na tym props'ie i tak naprawdę moim
zdaniem w tego typu rozwiązaniach powinno być już coś takiego jak Single
Source of Truth, czyli takie jedyne źródło prawdy, z którego komponenty
mogłyby czerpać sobie tego props'a i sprawdzać jaką wartość
w danym momencie mają mieć, a to wszystko moim zdaniem powinno być właśnie
oparte o router i o adres, na którym obecnie się znajdujemy, więc
teraz tej lekcji postaram się pokazać jak dokonać takiego refactoring'u
oczywiście część tego refactoring'u będzie przyspieszona, natomiast
samą pracę możesz wykonać samodzielnie lub możesz też
skorzystać z kodu następnej lekcji. Najpierw zerknijmy sobie na strukturę naszej
aplikacji i pomyślny gdzie moglibyśmy najlepiej osadzić jakiś
element, który mógłby sterować całą naszą aplikacją. Jeśli znasz
poprzedni kursy React od podstaw, to wiesz, że istnieje coś takiego jak
Context, który działa trochę podobnie jak tutaj provider do store'a, czyli
jeśli opleciemy sobie całą naszą aplikację, to każdy
komponent zawarty w naszej aplikacji będzie miał dostęp do wartości i
danych, które ten nasz provider będzie podawał i biorąc pod uwagę,
że ten komponent, który ma sterować nasza aplikacją musi korzystać
z naszego routera, to najlepiej, żeby on był opleciony właśnie
w nasz router, w nasz browser router, w tym przypadku i i pierwszym
elementem, który rzuca się tutaj w oczy jest main template, on zawiera w sobie całą naszą aplikację
i to on zawiera do do routera już, więc możemy sobie
do niego wejść i stworzyć logikę, dzięki której cała
nasza aplikacja będzie mogła korzystać z props'a, którego on utworzy w czasie rzeczywistym,
znajdując się na konkretnym route'cie. Zanim stworzymy
context to najpierw zbudujemy całą logikę odpowiedzialną za wybieranie
odpowiedniego props'a w odpowiednim czasie na podstawie właśnie raute'a, na którym się znajduje. Natomiast
z racji, że nasz main template. Jeśli sobie wejdziemy do root, widzimy że
on nie jest zawarty w komponencie raute, więc nie możemy
wykorzystać w nim takich props'ów jak na przykład match, który bardzo
prosty sposób jest w stanie znaleźć tą ścieżkę na której się znajdujemy, więc
musimy się tutaj trochę bardziej postarać. To co musimy zrobić, po pierwsze
to zaimportować sobie specjalną funkcję with router z naszego
React Router i with router, podobnie jak na przykład Connect
z React Redux oplata nam nasz, nasz komponent,
który eksportujemy, dając mu tym
samym dodatkowe props'y. Tego typu schemat nazywamy
High Order Component, czyli jakiś komponent przyjmuje komponent
jako parametr, a właściwie jako argument i dzięki
temu ten komponent, który tutaj wrzucamy dostaję dodatkowe rzeczy,
które możemy sobie później wyciągnąć tutaj w props'ach. Najpierw sprawdźmy
jakie props'y zostały podane do naszego komponentu, moglibyśmy
to zrobić za pomocą console log'a, ale z racji, że mamy nasze świetne narzędzie
deweloperskie, możemy sobie równie dobrze odpalić tutaj
nasz tab i znaleźć main template i w
nim zobaczymy, że match nie za wiele zawiera, natomiast
location path name zawiera właśnie ten string,
o który mu chodzi, czyli articles, notes albo twitters i teraz
wykorzystując tego props'a tutaj możemy stworzyć logikę, która będzie porównywać zestaw
trzech elementów z naszej tablicy. To będą trzy stringi, articles, twitters
i notes do bieżącej ścieżki. Jeśli jeden
z nich będzie pasował do tej bieżącej ścieżki, jeśli będzie ta ścieżka zawierać jeden
z nich w sobie, to znaczy, że jesteśmy na przykład właśnie w kategorii
articles i możemy zwrócić sobie takiego props'a, którego następnie podamy
do contextu. Jak zwykle brzmi to skomplikowanie i jak zwykle wcale takie nie jest,
więc teraz pokażę ci co możemy tutaj zrobić. Stworzymy sobie
komponent, w nim state i w tym state'cie
stworzymy sobie Page Type jako domyślny damy notes i oczywiście
stworzymy też funkcję Render i teraz stwórzmy
sobie Life Cycle Function, Component Did Mount, w którym
zawrzemy naszą logikę związaną właśnie z dobieraniem odpowiedniej wartości i
do ścieżki z porównywaniem jej właściwie, więc stwórzmy sobie Page Types
twitters articles i notes.
Zdestrukturyzujemy też sobie path name. Sprawdźmy
jeszcze czy to na pewno tak wyglądało, czy tam jest dokładnie taka konstrukcja
tego props'a. Props Location Path Name,
zgadza się i teraz stwórzmy
sobie comsta current page, w którym
zrobimy coś takiego. Przefiltrujemy sobie Page Types,
czyli wykorzystamy array method filter. Podamy page
i każdy page przyrównamy do path name. Sprawdzimy
czy on zawiera nasz page, czyli
wkładamy do past name include imię krótkakażdy masz page i jeśli
któryś z nich spełni ten warunek, to zostanie wypluty
jako string z tego filtra. Sprawdźmy
czy to zadziała. Jesteśmy na twitters i dostaliśmy twitters. Wchodzimy
na notes i nic się nie dzieje, ale jak odświeżymy to się dzieje. To
znaczy, że komponent tylko przy zamontowaniu wykonuje tę funkcję, a my chcemy,
żeby on też zupfate'owaniu się również ją
wykonywał, więc przenieśmy ją sobie teraz do czegoś co nazwiemy
na przykład set current page i ona
się wykona zarówno w component did mount, jak również w life cycle
method odpowiedzialnej za update'owanie, czyli component
did update i teraz za każdym razem jak zmienimy adres
naszej aplikacji, to dostajemy odpowiednią ścieżkę w tym
miejscu. To, co może nas jeszcze tutaj denerwować
I co pewnie musielibyśmy zmienić jeśli już będziemy nadpisywać nasz state to,
że zostaje tutaj zwrócone tablica, ale możemy się tego łatwo pozbyć, po prostu destrukturyzując
naszego consta, ale nie jak w przypadku obiektów klamrami, tylko nawiasami
kwadratowymi i to sprawi, że z tej tablicy wyciągamy sobie pierwszy
element, czyli jedyny, tego string'a i teraz mamy bardzo
ładne string'i. Tak ten żart był
celowy, więc teraz po stworzeniu sobie current page utwórzmy
w końcu this set state page
type current page. Ależ
mamy tutaj brzydki błąd. Wynika z faktu, że
w component will update nasz set state
się zapętla, czyli zmienia się state component
się update'uje, zmienia się state, component się update'uje i tak
w kółko. Żeby przerwać ten cykl, żeby złamać
po prostu te klątwę od odnawiania się state'u
musimy zrobić jedną rzecz. Komponent did update przyjmuje
dwa argumenty, to znaczy może je przyjąć prev props, czyli poprzednie
props'y, które zostały podane do tego komponentu i prev state. Prev state
jest zawsze drugim argumentem, dlatego
musimy wyciągnąć też ten pierwszy prev props i może nie będzie nam potrzebny i teraz
ten prev state, to jest właśnie poprzedni state, który istniał w naszym komponencie. Możemy
go podać sobie tutaj w tym miejscu, do naszej funkcji, naszej
funkcji set current page, powiedzieć słuchaj, potrzebujemy prev state, jeśli
go nie będzie to niech to będzie po prostu pusty string, to nam nic to nie zaszkodzi i teraz
musimy złamać jakoś ten cykl, więc stwórzmy sobie
taki warunek, że jeśli prev state page type
nie
jest równy current page,
to wtedy ustaw nam nowy
current page. Teraz
możemy sobie nawet wylogować, co
mamy w this state i zauważ,
że teraz jesteśmy w notatkach, przyjdziemy sobie do twitter'ów, pojawia się
nowy state i nowy i nowy i
tak dalej, więc w momencie kiedy on chce zrobić
nam kolejną rundę, kolejną pętle, kiedy już odnowił
nam state, czyli przeszedł na przykład do twitter'ów, ustawił na twitter'y, zupdate'tował
się. Znowu chce wykonać tę funkcję, leci przez te funkcje i patrzy i mówi tak,
poprzedni wtate był twitters, teraz mamy twitters, więc
nie wykonam tej operacji, która znajduje się w tym kondyszynal conditional'e. Jeśli
poprzedni state byłby inny od current page, wtedy
by wykonał, dlatego to zaczęło działać, więc uporaliśmy
się z tym dość skomplikowanym problemem, to teraz w następnej lekcji stworzymy
sobie właśnie context, w którym będziemy podawać nasz nowy utworzony state
do wszystkich komponentów naszej aplikacji. Pozbędziemy się tych paskudnych props'ów,
które strasznie nam brudzą cały kod.