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
export default WhiteLayout
export default WhiteLayout
- wstań
- podejdź i przywitaj się z nieznajomą osobą która jest najblizej
- powiedz coś o sobie przez 1min
- następnie daj szansę powiedzieć coś drugiej osobie przez 1min
- prowadzący daje sygnał do "zmiany!"
- powtarzaj punkty od 2 do 5 az prowadzący powie "koniec!"
export default WhiteLayout
export default WhiteLayout
export default WhiteLayout
export default WhiteLayout
- 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
- useState
- useEffect
- custom hooki
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', }} />
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
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
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ś 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ć
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
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
useState robimy na poziomie komponentu pojedynczego kontaktu, tak jest naprosiciej, tylko wtedy lista nie wiem ktory kompoennt jest
hoverowany
useState robimy na poziomie komponentu pojedynczego kontaktu,
tak jest naprosiciej, tylko wtedy lista nie wie ktory kompnent jest hoverowany
Ankieta live:
- Kto z Was uzywal juz useEffect?
- Kto robi to na codzien w pracy?
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ć.
<CodeMirror value={oficjalnieUseEffect} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />
Ogarniemy. Syntax
<CodeMirror value={syntaxUseEffect} options={{ mode: 'jsx', theme: 'night-owl', lineNumbers: false, readOnly: 'nocursor', }} />
Ogarniemy. 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
<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.
<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.
<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.
Jak zrobić tego useEffecta z pobieraniem?
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
Będzie miał podobną strukturę do useState, czyli zwróci array, pierwszy element to ulubiony, a drugi to
funkcja do updatowania ulubionego.
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