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 poprzedniej lekcji na code pen'ie udało nam się stworzyć taki
bardzo prosty store, w którym zaczęliśmy dodawać akcje,
które z kolei przechodzą do reducer'a, który z kolei modyfikuje
nasz store, a przynajmniej powinien modyfikować, bo na
razie zatrzymaliśmy się na consol log'u, który właśnie loguje nam to, co
znajduje się w naszej akcji. Teraz zanim przejdziemy do dalszego
kroku, czyli do modyfikacji naszego store'a, to jeszcze takie krótkie podsumowanie co
po kolei tutaj się dzieje. Przede wszystkim zaimportowaliśmy sobie metodę create store,
którą wyciągnęliśmy z redux'a, stworzyliśmy sobie consta store,
w którym właśnie ją wykorzystujemy, jako argument podajemy reducer,
który jest funkcją przyjmującą state i akcje,
state na samym początku kiedy tworzymy te funkcje nie
istnieje, dlatego musieliśmy podać initial state, żeby zapobiec
błędom i kiedy już reducer wie, że w razie gdyby było
tego state'u to sobie może to zaciągnąć, to zaczyna działać bardzo dobrze, przy
następnych akcjach, które będą do niego podawane kiedy ten state
już będzie istniał on będzie oczywiście brał ten bieżący state, który wyciągnie sobie
za stare'a, a nie ten, który my tutaj ustworzyliśmy, więc to co tutaj się znajduje
jest tylko na ten pierwszy inicjalny raz kiedy reducer się
odpala i jest podawany właśnie do naszego store, następnie
stworzyliśmy sobie akcje, która zawiera typ add note, konwencją
jest na nazywanie akcji właśnie w taki sposób, z podkreślnikami, czyli
tak zwany Snake Case i właśnie wielką literą pisane wszystko i drugim
kluczem w naszym Note Action jest payload, czyli też właśnie zgodnie
z konwencją zawartość tego co chcemy przekazać do store'a, to co my
chcemy tutaj dodać i właśnie skoro na story przetrzymuje notatki to payload'em
naszego Note Action, który zresztą nazywa się add note będzie nic innego
jak prosta, bardzo prosta notatka, ale żeby wysłać
tą notatkę do naszego stare'a musieliśmy wykorzystać metodę dispatch, dispatch
to jest właśnie metoda, która przyjmuje jako argument nazwę akcji, którą mamy wysłać
do naszego reducer'a i kiedy już się dowie jaką akcję mam wysłać to właśnie
dobrze się tym zajmuje, wysyła te akcje, ona jest podawana tutaj w naszym reducerze
jako drugi argument i możemy zrobić z nią naprawdę wiele na
razie ją tylko wylogowaliśmy, ale to co chcemy naprawdę tutaj zrobić
to sprawdzić czy Action Type to
Add Note, w ten sposób konfigurujemy
nasz reducer. Mówimy słuchaj, jeśli ta akcja będzie dodawanie
notatek, to ma zrobić bardzo konkretną rzecz. Masz
zwrócić nam nowy state i oczywiście, nie sztuką byłoby
zwrócić tutaj obiekt z nową notatkę, ale my przecież chcemy, żeby
każda notatka, którą dodajemy do naszego store'u zostawała w nim do póki my jej sami
nie usuniemy, więc nie możemy zrobić po prostu czegoś takiego, że zwrócimy
w naszym reducerze action kropka payload.
A zresztą możemy to zrobić
teraz i pokażę Ci jaki byłby tego efekt. Przede wszystkim taka akcja
nic tam nie da, bo tutaj będzie mieć syntax error, nie możemy w taki sposób wykorzystać kropki,
więc mamy dwa wyjścia albo otworzymy sobie const'a, z którego
wyciągamy sobie payload, w taki sposób naszej akcji albo
możemy zrobić to od razu tutaj do destrukturyzując nasz argument payload
i type potrzebujemy, ponieważ type podajemy tutaj w tym miejscu, w naszym
warunku, więc jeśli type jest add note to zwracamy payload i teraz
to powinno działać i żeby
podejrzeć to, co znajduje się w naszym storze w danej chwili, możemy wykorzystać kolejną
bardzo fajną metodę, nazywa get state, ale
żeby podejrzeć co w niej jest, a właściwie co nam zwraca no to musimy to wrzucić
w console log'a i naszym oczom
ukazał się taki oto obraz. Mamy tutaj payload, który wrzuciliśmy
w naszej akcji. Problem jest taki, że jeśli stworzymy sobie drugą
akcje, na przykład Note Action
2, wrzucimy tutaj dwójki żebyśmy się zorientowali,
która jest która i zdispatch'ujemy drugą,
czyli tak naprawdę chcielibyśmy tą akcję tutaj dodać kolejną
notatkę do naszego store'a, ale utrzymując tę pierwszą też, bo tak powinny
działać te akcje, ale tak naprawdę to co się wydarzy to
w naszym storze zostanie zachowana tylko ta druga notatka, wynika
to z tego, że nawet jeśli nawet zidentyfikujemy sobie tutaj naszą
akcję to nadpisujemy cały nasz store nową
akcją, która przyszła. Nie patrzymy w ogóle na to co bierzemy sobie
tutaj jako argument do naszej funkcji w reducerze, a nie
bez powodu przecież nawiązujemy do naszego state'u, bo chcemy stworzyć taką logikę, która
będzie łączyć poprzedni state, który istniał przed wywołaniem jakieś
akcji, z tym payload'em, który przyszedł w nowej akcji i z
racji, że nasz state wygląda w taki sposób, że mamy tutaj zagnieżdżony klucz
notes, który jest pustą tablicą to również tutaj musimy
przygotować taką notację, czyli jeśli chcemy dodać notatkę to
musimy powiedzieć słuchaj zwróć mi tutaj tablice
notes, która będzie zawierać state notes, czyli
te wszystkie notatki, które do tej pory istniały w naszym state'cie, a jako
następną notatkę dodaj mi payload, czyli tę nową
notatkę, która przyszła z naszą akcją i jak
widzisz teraz obie notatki pojawiły się w naszym state'cie,
problem jest niestety taki, że przy takiej notacji tablice
będą nam się ciągle zagnieżdżać. Wynika to z tego, że dodajemy tablice do
tablicy do tablicy do tablicy i w efekcie mamy na przykład takie
coś jak tutaj, więc przy każdej operacji na naszym
storze musimy spłaszczać te tablice za pomocą spread operator'a, a
możemy to zrobić najprościej po prostu wykorzystując spread
operator na całym naszym state'cie związanym z notatkami i teraz jeśli
sobie zobaczysz tutaj na naszego consol log'a to mamy jedną tablicę zawierającą dwa
obiekty, czyli to co chcieliśmy uzyskać.