Skip to content

Latest commit

 

History

History
1149 lines (948 loc) · 26.2 KB

deck.mdx

File metadata and controls

1149 lines (948 loc) · 26.2 KB

import './script.js' import {Appear} from 'mdx-deck' import WhiteLayout from './components/white-layout' import {RandomlyPlaced} from './components/randomly-placed' import DemoLayout from './components/demo-layout' import {UnControlled as CodeMirror} from 'react-codemirror2'

import { useState, setState, oldState, intersujeNasUseState, syntaxUseState, wiecejStatowUse, wiecejStateowNieUse, innaczejUseState, lazyUseState, hoverCode, filtrowaniePoImieniu, oficjalnieUseEffect, syntaxUseEffect, przykladowoUseEffectSub, przykladowoUseEffectDeps, kilkaUseEffect, jaChceTylkoRaz, useEffectRozwiazanie, useFavCustom, useFavCode, czystaFunkcja } from './code'

export {default as theme} from './theme'

export default WhiteLayout

⚛️ React Hooks ⚛️

⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️⚛️

export default WhiteLayout

Poznajmy się!

Za moment rozpoczniemy icebreakera

Przełamiemy lody i poznamy innych uczestników oraz mentorów


export default WhiteLayout

Jak to?!

To będzie test z rozumienia algorytmu:

  1. wstań
  2. podejdź i przywitaj się z nieznajomą osobą która jest najblizej
  3. powiedz coś o sobie przez 1min
  4. następnie daj szansę powiedzieć coś drugiej osobie przez 1min
  5. prowadzący daje sygnał do "zmiany!"
  6. powtarzaj punkty od 2 do 5 az prowadzący powie "koniec!"


export default WhiteLayout

Okay, mamy to za sobą...


export default WhiteLayout

Bartek Widlarz
Blog techniczny: bwidlarz.com
React
React Native
TypeScript
Swift
Kotlin
Elixir
Fullstack Serverless

export default WhiteLayout

Mentorzy 👏

Bartłomiej Bajda
Daniel Grychtoł
Kamil Szubrycht
Katarzyna Tobiś
Michał Czapkowicz

export default WhiteLayout

Agenda

  • 9:00 - 10:00 - różności
  • 10:00 - 10:15 - przerwa
  • 10:15 - 12:30 - I etap
  • 12:30 - 13:15 - jemy pizze
  • 13:15 - 16:00 - II etap
  • Fajne rzeczy: https://github.com/TheWidlarzGroup

export default WhiteLayout

O czym są te warsztaty

  • useState
  • useEffect
  • custom hooki

🚀 Let's get started 🚀


Potrzebowałeś mieć stan albo efekty uboczne w komponencie Reactowym
= klasa
Nie potrzebowałeś
= funkcja

W wielu opracowaniach na temat React Hooksów można znaleźć tak napisany komponent z podpisem że to jest komponent klasowy.
Ktoś z Was piszę tak komponenty dzisiaj?
Coś Wam tutaj nie pasuje?
Tak, nie potrzebujemy bindować, nie potrzeba konstruktora.

<CodeMirror value={oldState} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />

bind?
a gdzie fat arrow?
constructor lol
jak to mozna state = i jest
który mamy rok?!
REKLAMA HOOKÓW!

Tutaj już odchudzona wersja.
Taką pewnie piszecie na codzień.
Ten komponent używa setState do ustawiania swojego stanu wewnętrznego. 

<CodeMirror value={setState} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


A tak wygląda komponent który używa hooka useState do tego samego celu.  

<CodeMirror value={useState} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


Kilka rzeczy odnośnie hooków omówimy na przykładzie useState a kilka na useEffect

useState


tak wygląda syntax z useState
jest tutaj kilka rzeczy
- hook useState przyjmuje wartość początkową stanu w przy przypadku 0
- zwraca tablice gdzie pierwszym elementem jest aktualna wartość stanu,
- drugim elementem jest setter dla stanu, jest to funkcja która przyjmuje jako wartość nową wartość stanu

<CodeMirror value={syntaxUseState} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


To co jest fajne w tym nowym syntaxie to to że dostajemy od razu settery 
i nie musimy przepuszczać nowego stanu przez setState

<CodeMirror value={wiecejStatowUse} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


a tak wygląda kied mamy setStaty, dobrze po prostu pisac te pomocnicze funkcje

<CodeMirror value={wiecejStateowNieUse} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


możemy też udpateować state funkcja, przez co nie musimy się odnosić do statu bezpośrednio

<CodeMirror value={innaczejUseState} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


możemy podać funkcje do initial statu, po to żeby zrobić ustalanie tego początkowego stanu leniwie

<CodeMirror value={lazyUseState} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


funkcje bez efektów ubocznych

Czym są czyste funkcje?

(pure function)


y = x + 1

dla x = 10

11
11
11
dla danych wejściowych x, funkcja zwraca zawsze ten sam wynik
ZAWSZE
TEN
SAM
WYNIK

czy ta funkcja jest czysta?
matematycznie nie jest
wiec jak jest?
jest czysta na innym poziomie
jezeli wezmiemy pod uwage ze kazdy komponent to jest funkcja propsow i stanu
to taki komponent zawsze bedzie zwracał ten sam wynik przy tej samej konfiguracji propsow i stanu
w tym sensie jest czysty i w tym sensie hooki zbliazaja nas do programowania funkcyjnego

<CodeMirror value={useState} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


Czyste funkcje są proste dla ludzi i maszyn. 
Funkcji uczyliśmy się w podstawówce na matmie.
Na odmianę przejdźmy na chwilę do klas...

<CodeMirror value={czystaFunkcja} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


Kto potrafi wymienić reguły jak bindowane jest this w JavaScriptowych klasach?



Ktoś na rekrutacji będzie Was pytał o `this`? Nie, bo rekrutujący sami nie wiedzą. 
Tylko że potem podczas pisania kodu, to Wy będziecie siedzieć i debugować i się frustrować

...bo ja nie xD


"...this is not an author-time binding but a runtime binding. It is contextual based on the conditions of the function's invocation. this binding has nothing to do with where a function is declared, but has instead everything to do with the manner in which the function is called."

You dont know JS


Funkcje są prostsze od klas. 
Temu cięzko zaprzeczyć
Funkcji uczyiśmy się w podstawowce
A tego jak dzialaja jsowe klasy niektorzy z nas nigdy sie nie nauczyc

Ale czy hooki są bez wad?
Sami zobaczycie
Ale póki co mam dla was pierwszy zestaw złych wiesci
zeby uzywac hookow, trzeba pamietac o paru regulach
Funkcje są prostsze
Ale czy Hooki są bez wad?
Jak chcesz uzywac hooków, musisz nauczyc się paru reguł

w oficjalnej dokumentacji jest mowa o 2 regulach
ale prawda jest taka ze jest ich 3
mowią one o tym jakie sa ograniczenia w uzywaniu hookow

"Rules of Hooks"

1. Uzywaj hooków tylko na poziomie komponentu, bezpośrednio w jego zakresie. Nie w pętli, nie w ifie, nie w zagniezdzonej funkcji
2. Nie uzywaj hooków poza funkcyjnymi komponentami oraz własnymi hookami.

Czas na pierwsze zadania!

1. Zbuduj prosty komponent do wyświetlania pojedynczego kontaktu (Hint: you can use randomuser.me for user data - just copy it over to your code.)
2. Zbuduj komponent który wyświetla listę kontaktów
3. Pokazuj/chowaj szczegóły kontaktu po najechaniu kursorem (bez uzycia hover CSS)
4. Dodaj funkcjonalność filtrowania po imieniu
5. ⭐Dodaj przycisk po kliknieciu spowoduje ze szczegóły kontaktu będą cały czas widoczne
6. ⭐Filtruj po wszystkich polach, nie tylko po imieniu
7. ⭐Filtrowanie powinno być niewrazliwe na wielkosc liter
8. ⭐Dodaj przycisk do sortowania kontaktów po imieniu; kliknięcie przycisku spowoduje zmiane kierunku sortowania
9. ⭐Dodaj ikone kierunku sortowania (↑/↓)


useState robimy na poziomie komponentu pojedynczego kontaktu, tak jest naprosiciej, tylko wtedy lista nie wiem ktory kompoennt jest 
hoverowany

Hover


useState robimy na poziomie komponentu pojedynczego kontaktu, 
tak jest naprosiciej, tylko wtedy lista nie wie ktory kompnent jest hoverowany

Filtrowanie po imieniu


Ankieta live:
- Kto z Was uzywal juz useEffect?
- Kto robi to na codzien w pracy?

useEffect!

No to teraz zaczyna się magia!

To jest oficjalny przykład z dokumentacji. 
Nie musieliście zarywać soboty zeby go zobaczyc.

- jest useState i useEffect
- klikasz button, on reaguje odpaleniem setCount z nową, większa wartością
- to triggeruje odpaleniem funkcji Example jeszcze raz. 
To co jest w return trafia plus minus na ekran, z nowym count. 
- następnie react sprawdza co jest w useEffect i to też odpala

1. Moze byc trudno uwierzyć, ale useEffect słuzy przede wszystkim do synchronizacji danych 
2. jest niskopoziomowym API który jest dość złozony i malo intuicyjny
3. razem z useState oraz paroma innymi pozwala tworzyć własne hooki

Wiem co chcecie zapytać.

To jest oficjalny przykład:

<CodeMirror value={oficjalnieUseEffect} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />

Jak zyc bez cyklu zycia..?
Gdzie pobierac dane?
Słyszaleś kiedyś o animacjach?
To teraz gdzie mogę ustawić listenera?
Ogarniemy

Ogarniemy. Syntax

Ogarniamy. Syntax.

<CodeMirror value={syntaxUseEffect} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


Ogarniemy. Subskrybujemy się.

Ogarniamy. Subskrybujemy się.

<CodeMirror value={przykladowoUseEffectSub} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


Ogarniemy. Deps.


React chce zeby useEffect wiedział od czego zalezna jest ta logika w useEffect
Potrzebuje tego zeby wiedziec czy ma włączyć ten kod do synchronizacji podczas jego odpalenia czy nie. 

I tutaj mozna dlugo mowic o depsach. Bo co np. kiedy uzywamy w useEffect funkcji, która ma jakąś zaleznosc? W wiekszosci przypadkow wystarczy wyciagnac tę funkcje całkiem poza komponent. Innym razem mozna wsadzic te funkcje do useEffect. Są scenariusze kiedy obie strategie zawodza, wtedy... wtedy zapraszam na kolejne warsztaty gdzie zajmiemy sie między innymi useCallback i useReducer :D 

Ogarniemy. Deps.

<CodeMirror value={przykladowoUseEffectDeps} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />


Ogarniamy już syntax. Co dalej?

0. Kolejność dzialania jest taka. React najpierw renderuje tego jsx'a potem pyta sie komponentu co tam dla mnie masz w tym useEffect. React decyduje sie na uruchomienie zawartosci useEffecta po kazdym renderze.

1. Uwaga, jesteśmy w funkcjach, i domknięciach. Jak useEffect się domknie na danym zestawie propsow i state'u, to nie będzie wiedział o nowych. 

W klasach jest inaczej, w klasach, funkcje podrózują w czasie. Przez to ze `this` jest mutowalny. Oczywiście mozna to naprawić, ale to nie na teraz.

Ogarniamy już syntax. Co dalej?

<CodeMirror value={oficjalnieUseEffect} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />



Mozna mieć więcej niz jeden useEffect w komponencie. Czyli mozemy rozdzielic logike na mniejsze, adekwatne fragmenty. Jakby porównanc do componenDidMount gdzie trzeba bylo wszystko do jego wrzucac do na plus.

Kazdy useEffect dostaje wtedy swoje depsy.

Można mieć więcej niż jeden useEffect

<CodeMirror value={kilkaUseEffect} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />



Oszukiwanie. 
Kto nigdy nie okłamał niech pierwszy rzuci kamień.
Na czym polega oszustwo tutaj?

Że podaje że ten useEffect nie ma żadnych zależności, a ma - count.
Jaki jest tego skutek? 
useEffect zostanie odpalony tylko raz, a nie co każdy render. 
I nie jak się count zmieni.



Oszukiwanie


Ankieta: bit.ly/hooks-krk


Czas na kolejne zadania!

Podpowiedź od razu: będziecie musieli trochę łamać reguły
1. Zamiast hardcodować listę kontaktów, pobierz 5 kontaktów z API, np. z randomuser.me
2. Dodaj loader ktory sie wyświetla podczas pobierania danych
3. ⭐Dodaj error handling gdyby coś poszło nie tak
4. ⭐Dodaj button “Załaduj jeszcze 3” po kliknięciu doładuj 3 elementy z API


Jak zrobić tego useEffecta z pobieraniem?

Pobieranie z API


Rób co chcesz. 
Tworzymy sobie wspólnie hooka useFavouriteContact
Czyli będziemy przechowywać w localStorage jeden kontakt, który będziemy traktować jako ulubiony. 
Będzie miał podobną strukturę do useState, czyli zwróci array, pierwszy element to ulubiony, a drugi to 
funkcja do updatowania ulubionego 

useCoChcesz

Może useFavouriteContact?

Będzie miał podobną strukturę do useState, czyli zwróci array, pierwszy element to ulubiony, a drugi to 
funkcja do updatowania ulubionego.

API


Gotowi żeby to zobaczyć? 

Ten syntax z useStatem, że przyjmuje funkcje, to jest lazy loading. Można się tutaj bardziej rozpisać z logiką trochę jak ktoś potrzebuje

Gotowiec


Czas na pisanie własnych hooków!

1. Dodaj do hooka useFavouriteContact możliwość zapisywania całej listy ulubionych kontaktów (useFavouriteContacts)
2. Stwórz hooka useFetch, który robi fetch na danym URL. Najlepiej, żeby oddawał stan loading, error i odpowiedź.
3. Stwórz hooka, który nasłuchuje na pozycje kursora opuszczającego ekran i pokaż w tym czasie Alert "Nie zostawiaj nas!"
4. Stwórz wyszukiwarkę dla kontaktów (auto-completion input) budując hooka useSuggestion
5. ⭐Generalizuj działanie hooka useFavouriteContacts tak, żeby można było za jego pomocą zapisywać dowolne dane w localStorage
6. ⭐Generalizuj tego hooka tak, żeby można było wybrać typ storage


Dziękujemy za udział!


⚛️ React Hooks ⚛️

07.03.2020 Kraków, Poland