From 12894492f66717da844bb753deb21dcb4a503e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Podlouck=C3=BD?= Date: Fri, 3 Nov 2023 09:00:59 +0100 Subject: [PATCH 1/2] =?UTF-8?q?Aktualizace=20obsahu=20lekce=20o=20formul?= =?UTF-8?q?=C3=A1=C5=99=C3=ADch=20a=20efektech.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- daweb/react/formulare-efekty/cv-efekty-api.md | 1 + .../formulare-efekty/cv-formularove-prvky.md | 6 +++ .../react/formulare-efekty/cvlekce/binding.md | 9 ++++ .../react/formulare-efekty/cvlekce/efekty.md | 9 ++++ .../cvlekce/prazsky-cas/exercise.md | 4 +- .../cvlekce/registrace/exercise.md | 26 ++------- .../cvlekce/vyber-zony/exercise.md | 1 + daweb/react/formulare-efekty/efekty-api.md | 26 ++++++--- .../formulare-efekty/efekty-zavislosti.md | 54 +++++++++++++++++++ daweb/react/formulare-efekty/efekty.md | 8 +-- daweb/react/formulare-efekty/entry.yml | 7 +-- .../formulare-efekty/formularove-prvky.md | 13 +++-- daweb/react/formulare-efekty/shrnuti.md | 7 +++ .../formulare-efekty/specializovane-efekty.md | 19 ------- 14 files changed, 128 insertions(+), 62 deletions(-) create mode 100644 daweb/react/formulare-efekty/cvlekce/binding.md create mode 100644 daweb/react/formulare-efekty/cvlekce/efekty.md create mode 100644 daweb/react/formulare-efekty/efekty-zavislosti.md create mode 100644 daweb/react/formulare-efekty/shrnuti.md delete mode 100644 daweb/react/formulare-efekty/specializovane-efekty.md diff --git a/daweb/react/formulare-efekty/cv-efekty-api.md b/daweb/react/formulare-efekty/cv-efekty-api.md index 60cd102d..19e31c46 100644 --- a/daweb/react/formulare-efekty/cv-efekty-api.md +++ b/daweb/react/formulare-efekty/cv-efekty-api.md @@ -1,4 +1,5 @@ ## Cvičení: Efekty a volání API +::exc[cvlekce/efekty] ::exc[cvlekce/prazsky-cas] ::exc[cvlekce/vyber-zony] diff --git a/daweb/react/formulare-efekty/cv-formularove-prvky.md b/daweb/react/formulare-efekty/cv-formularove-prvky.md index d0e88464..65aa9873 100644 --- a/daweb/react/formulare-efekty/cv-formularove-prvky.md +++ b/daweb/react/formulare-efekty/cv-formularove-prvky.md @@ -1,5 +1,11 @@ ## Cvičení: Formulářové prvky +::exc[cvlekce/binding] ::exc[cvlekce/registrace] ::exc[cvlekce/vyber-zeme] + +## Bonusy + +Pokud máte ještě čas, můžete si vyzkoušet následující cvičení, případně si je nechte jako úložky na doma. + ::exc[cvlekce/zasilani-newsletteru] diff --git a/daweb/react/formulare-efekty/cvlekce/binding.md b/daweb/react/formulare-efekty/cvlekce/binding.md new file mode 100644 index 00000000..7719ecba --- /dev/null +++ b/daweb/react/formulare-efekty/cvlekce/binding.md @@ -0,0 +1,9 @@ +--- +title: Data binding +lead: Vyzkoušejte si obousměrný data binding. +demand: 3 +solutionAccess: lock +--- + +1. Vytvořte si repozitář ze šablony [cviceni-data-binding](https://github.com/Czechitas-podklady-WEB/cviceni-data-binding). +1. Následujte instrukce z README repozitáře. diff --git a/daweb/react/formulare-efekty/cvlekce/efekty.md b/daweb/react/formulare-efekty/cvlekce/efekty.md new file mode 100644 index 00000000..18b09516 --- /dev/null +++ b/daweb/react/formulare-efekty/cvlekce/efekty.md @@ -0,0 +1,9 @@ +--- +title: Efekty +lead: Vyzkoušejte si vytvořit jednoduché efekty. +demand: 3 +solutionAccess: lock +--- + +1. Vytvořte si repozitář ze šablony [cviceni-react-efekty](https://github.com/Czechitas-podklady-WEB/cviceni-react-efekty). +1. Následujte instrukce z README repozitáře. diff --git a/daweb/react/formulare-efekty/cvlekce/prazsky-cas/exercise.md b/daweb/react/formulare-efekty/cvlekce/prazsky-cas/exercise.md index d199ed43..0c690104 100644 --- a/daweb/react/formulare-efekty/cvlekce/prazsky-cas/exercise.md +++ b/daweb/react/formulare-efekty/cvlekce/prazsky-cas/exercise.md @@ -1,12 +1,14 @@ --- title: Pražský čas +lead: Vytvořte jednoduchou aplikaci, která zobrazuje aktuální čas v Praze. demand: 2 +solutionAccess: lock --- ::fig[ukázka řešení]{src=assets/ukazka-reseni.png} 1. Založte si novou React aplikaci podle klasického postupu. -1. Uvnitř komponenty `App` vytvořte jednoduchý efekt, který se spustí pří prvním zobrazení komponenty. Uvnitř tohoto efektu zavolejte funkci `alert` a zobrazte vyskakovací okno s nějakou zprávou. +1. Uvnitř komponenty `HomePage` vytvořte jednoduchý efekt, který se spustí pří prvním zobrazení komponenty. Uvnitř tohoto efektu zavolejte funkci `alert` a zobrazte vyskakovací okno s nějakou zprávou. 1. Přidejte do vaší komponenty stav `datetime`, jehož výchozí hodnota bude prázdný řetězec. V efektu smažte volání `alert` a uložte do stavu nějaký čas jako řetězec ve formátu ``` diff --git a/daweb/react/formulare-efekty/cvlekce/registrace/exercise.md b/daweb/react/formulare-efekty/cvlekce/registrace/exercise.md index befb9496..e1baf074 100644 --- a/daweb/react/formulare-efekty/cvlekce/registrace/exercise.md +++ b/daweb/react/formulare-efekty/cvlekce/registrace/exercise.md @@ -1,33 +1,15 @@ --- title: Registrace +lead: Vytvořte jednoduchý formulář pro registraci uživatele. demand: 3 +solutionAccess: lock --- ::fig[ukázka řešení]{src=assets/ukazka-reseni.gif} 1. Založte si novou React aplikaci dle klasického postupu. -1. Vytvořte komponentu `App` s jednoduchým textovým políčkem dle následujícího vzoru. - - ```jsx - const App = () => { - const handleSubmit = (event) => { - event.preventDefault(); - }; - - return ( -
- - -
- ); - }; - ``` - -1. Na políčko přidejte událost `onChange`. V reakci na událost do konzole vypište obsah políčka pomocí vlastnosti `target.value`. Vyzkoušejte, že když do políčka píšete, v konzoli vidíte každou změnu jeho hodnoty. -1. Uvnitř komponenty `App` vytvořte stav `userName` s výchozí hodnotou prázdný řetězec. Vytvořte obousměrný (two-way) data binding mezi textovým políčkem a stavem `userName`. +1. V komponentě `HomePage` vytvořte jednoduchý formulář pro registraci uživatele. Formulář bude obsahovat jedno textové políčko pro zadání uživatelského jména a tlačítko pro odeslání formuláře s textem _Registrovat_. +1. Uvnitř `HomePage` vytvořte stav `userName` s výchozí hodnotou prázdný řetězec. Vytvořte obousměrný (two-way) data binding mezi textovým políčkem a stavem `userName`. 1. V reakci na událost `onSubmit` pomocí funkce `alert` vypište jméno uživatele uložené ve stavu `userName`. 1. Na stránku vložte `div` se zprávou ```text diff --git a/daweb/react/formulare-efekty/cvlekce/vyber-zony/exercise.md b/daweb/react/formulare-efekty/cvlekce/vyber-zony/exercise.md index b13ef6f8..d30d5533 100644 --- a/daweb/react/formulare-efekty/cvlekce/vyber-zony/exercise.md +++ b/daweb/react/formulare-efekty/cvlekce/vyber-zony/exercise.md @@ -1,5 +1,6 @@ --- title: Výběr zóny +lead: Vytvořte aplikaci, která zobrazuje aktuální čas ve zvolené časové zóně. demand: 2 --- diff --git a/daweb/react/formulare-efekty/efekty-api.md b/daweb/react/formulare-efekty/efekty-api.md index eb018939..a00d1ed5 100644 --- a/daweb/react/formulare-efekty/efekty-api.md +++ b/daweb/react/formulare-efekty/efekty-api.md @@ -1,17 +1,21 @@ ## Efekty a volání API -Pokud chceme v naší aplikaci zobrazovat data z nějakého API, musíme si tato data stáhnout pomocí nám již známé funkce `fetch`. Tuto funkci je nejlepší zavolat právě ve chvíli, kdy se naše komponenta poprvé objeví na stránce. +Pokud chceme v naší aplikaci zobrazovat data z nějakého API, musíme si tato data stáhnout pomocí nám již známé funkce `fetch`. V čiistéme JavaScriptu jsme byli zvýklí tuto funkci volat ve chvíli, kdy se načítá naše stránka a načíst si všechna data pro celou stránku najednou. V Reactu však můžeme načítat data jen pro každou komponentu zvlášť. Funkci `fetch` tak budeme chtít volat ve chvíli, kdy se naše komponenta poprvé objeví na stránce. To zní jako případ pro použale můžeme ji pojmenovat jakkoliv.ití efektů. Naše poslední aplikace zatím zobrazovala, že svátek má Jiří. To je však pravda pouze jeden den v roce. Pojďme aplikaci vylepšit tak, aby si stáhla aktuální jméno z API. ```js -const App = () => { +const HomePage = () => { const [name, setName] = useState(''); useEffect(() => { - fetch('https://svatky.adresa.info/json') - .then((response) => response.json()) - .then((data) => setName(data[0].name)); + const fetchName = async () => { + const response = await fetch('https://nameday.abalin.net/api/V1/today'); + const data = await response.json(); + setName(data.nameday.cz); + }; + + fetchName(); }, []); return ( @@ -23,4 +27,14 @@ const App = () => { }; ``` -Výsledný kód si můžete prohlédnout v [Codesandboxu zde](https://codesandbox.io/s/da-web-svatky-ndwfg2?file=/src/App.jsx). +Povšimněte si funkce `fetchName`, kterou jsme si vytvořili přimo uvnitř efektu k tomu, aby získala jméno z API a nastavila jej do stavu. Funkci `fetchName` jsme museli vytvořit, neboť efekt sám o sobě nemůže být asynchronní. V Reactu Nemůžeme udělat toto: + +```js +useEffect(async () => { + const response = await fetch('https://nameday.abalin.net/api/V1/today'); + const data = await response.json(); + setName(data.nameday.cz); +}, []); +``` + +Z tohoto důvodu si vždy pro fetchování dat vytvoříme pomocnou funkci, kterou pak v efektu ihned zavoláme. V našem případě jsme funkci nazvali `fetchName`, protože stahuje jméno z API. diff --git a/daweb/react/formulare-efekty/efekty-zavislosti.md b/daweb/react/formulare-efekty/efekty-zavislosti.md new file mode 100644 index 00000000..9af968e4 --- /dev/null +++ b/daweb/react/formulare-efekty/efekty-zavislosti.md @@ -0,0 +1,54 @@ +## Efekty se závislostmi + +Zatím jsme viděli efekty, které se spouštějí pouze jednou, tedy ve chvíli, kdy se komponenta poprvé objeví na stránce. Občas však potřebujeme efekt, který se spustí pokaždé, když se změní nějaká stavová proměnná nebo _prop_. Takový efekt vyrobíme tak, že do hranatých závorek napíšeme stavovou proměnnou nebo _prop_, na kterou má efekt reagovat, nebo-li na které spuštění efektu záviset. + +```js +const Komponenta = () => { + const [datum, setDatum] = useState('2022-05-14'); + + useEffect(() => { + console.log(`Hodnota stavové proměnné datum je ${datum}.`); + }, [datum]); + + // … +}; +``` + +Tato technika se nám hodí nejčastějí ve chvíli, kdy chceme stáhnout nějaká data z API ve chvíli, kdy komponenta změní svůj stav. V našem příkladu si stáhneme jméno z API, které má svátek v den, který uživatel vybere v kalendáři. + +```jsx +export const HomePage = () => { + const [name, setName] = useState(''); + const [datum, setDatum] = useState('2022-11-11'); + + useEffect(() => { + const fetchName = async () => { + const [rok, mesic, den] = datum.split("-"); + const response = await fetch( + `https://nameday.abalin.net/api/V1/getdate?day=${den}&month=${mesic}` + ); + const data = await response.json(); + setName(data.namedays.cz); + }; + + fetchName(); + }, [datum]); + + return ( + <> +
+

Svátky

+ +
V tento den má svátek {name}
+
+ + ); +}; +``` diff --git a/daweb/react/formulare-efekty/efekty.md b/daweb/react/formulare-efekty/efekty.md index 045e0ca7..85f1c67a 100644 --- a/daweb/react/formulare-efekty/efekty.md +++ b/daweb/react/formulare-efekty/efekty.md @@ -2,10 +2,10 @@ V mírně komplikovanějších React aplikacích brzy narazíme na potřebu zareagovat na určité situace, které nastávají během vykreslování (renderování) komponenty. Budeme chtít například spustit nějaký kód ve chvíli, kdy se komponenta poprvé objeví na stránce. Čas od času také budeme chtít v komponentě provést něco ve chvíli, kdy se změní hodnota v props nebo ve stavu. K tomuto nám v Reactu slouží takzvané :term{cs="efekty" en="effects"}. -Efekty jsou v podstatě velmi podobné událostem. Ve chvíli, kdy uvnitř komponenty něco nastane, budeme chtít zavolat naši funkci. Jako příklad si vyrobíme jednoduchou aplikaci, která řiká, kdo má zrovna svátek. +Efekty jsou v podstatě velmi podobné událostem. Ve chvíli, kdy uvnitř komponenty něco nastane, budeme chtít zavolat námi definovanou funkci. Jako příklad si vyrobíme jednoduchou aplikaci, která řiká, kdo má zrovna svátek. ```js -const App = () => { +const HomePage = () => { return ( <>

Svátky

@@ -15,10 +15,10 @@ const App = () => { }; ``` -Pokud bychom chtěli spustit kousek kódu ve chvíli, kdy se naše komponenta `App` objeví na stránce, použijeme funkci `useEffect` a té předáme námi vytvořenou funkci. +Pokud bychom chtěli spustit kousek kódu ve chvíli, kdy se naše komponenta `HomePage` objeví na stránce, použijeme funkci `useEffect` a té předáme námi vytvořenou funkci. ```js -const App = () => { +const HomePage = () => { useEffect(() => { console.log('jsem tady'); }, []); diff --git a/daweb/react/formulare-efekty/entry.yml b/daweb/react/formulare-efekty/entry.yml index 0aaeb6ed..15cf7fbf 100644 --- a/daweb/react/formulare-efekty/entry.yml +++ b/daweb/react/formulare-efekty/entry.yml @@ -1,10 +1,11 @@ title: Formulářové prvky, efekty -lead: 'Zapojíme do našich React aplikací formulářové prvky a ukážeme si, jak pomocí efektů volat API.' -access: 'claim' +lead: Zapojíme do našich React aplikací formulářové prvky a ukážeme si, jak pomocí efektů volat API. +access: claim sections: - formularove-prvky - cv-formularove-prvky - efekty - efekty-api - - specializovane-efekty + - efekty-zavislosti - cv-efekty-api + - shrnuti diff --git a/daweb/react/formulare-efekty/formularove-prvky.md b/daweb/react/formulare-efekty/formularove-prvky.md index 18b108db..53676cc6 100644 --- a/daweb/react/formulare-efekty/formularove-prvky.md +++ b/daweb/react/formulare-efekty/formularove-prvky.md @@ -1,7 +1,7 @@ -Díky tomu, že jsme se v minulé lekci naučili pracovat se stavem, otvírají se nám v Reactu mnohé nové možnosti. - ## Formulářové prvky +Díky tomu, že jsme se v minulé lekci naučili pracovat se stavem, otvírají se nám v Reactu mnohé nové možnosti. + Formulářové prvky jako textová políčka, zaškrtávací tlačítka apod. jsou jedním z hlavních způsobů, jak získat vstup od uživatele. V čistém JavaScritpu jsme zvyklí získávat hodnoty z těchto prvků tak, že je vybereme pomocí `querySelector` a použijeme například vlastnost `value`. ```html @@ -16,7 +16,7 @@ const ageInput = document.querySelector('#age-input'); console.log(ageInput.value); ``` -V Reactu však k DOM elementům na stránce přístup nemáme. Hodnotu uvnitř textového políčka si tak musíme uložit do stavu. +V Reactu však k DOM elementům na stránce přístup nemáme. Hodnotu uvnitř textového políčka si tak musíme uložit do stavu, abychom se k ní mohli dostat, když ji budeme potřebovat. Představme si jednoduchou komponentu, kde uživatel zadá svůj věk podobně jako v příkladu výše. @@ -45,10 +45,9 @@ const AgeField = () => { Tímto postupem se snažíme provázat obsah políčka s hodnotou ve stavu. Kdykoliv uživatel obsah políčka změní, my na to zareagujeme změnou stavu `age`. Tomuto principu se anglicky říká data binding. -Pozor však, že náš data binding zatím funguje pouze jedním směrem, tedy _změna políčka_ ⟶ -_změna stavu_. Pokud se z nějakého důvodu změní hodnota ve stavu `age`, obsah políčka se zatím neaktualizuje. +Pozor však, že náš data binding zatím funguje pouze jedním směrem, tedy _změna políčka_ ⟶ _změna stavu_. Pokud se z nějakého důvodu změní hodnota ve stavu `age`, obsah políčka se zatím neaktualizuje. -### Obousměrný data binding +## Obousměrný data binding V praxi téměř vždy budeme chtít takzvaný two-way (obousměrný) data binding. To zařídíme jednoduše tak, že hodnotu ve stavu vždy nastavíme jako hodnotu políčka. @@ -65,4 +64,4 @@ const AgeField = () => { }; ``` -Takto zajistíme provázanost i druhým směrem, tedy _změna stavu_ ⟶ _změna políčka_. Nyní, když změníme obsah políčka, změní se nám stav. A když naopak změníme stav, změní se nám obsah políčka. +Takto zajistíme provázanost i druhým směrem, tedy _změna stavu_ ⟶ _změna políčka_. Nyní, když změníme obsah políčka, změní se náš stav. A když naopak změníme stav, změní se obsah políčka. diff --git a/daweb/react/formulare-efekty/shrnuti.md b/daweb/react/formulare-efekty/shrnuti.md new file mode 100644 index 00000000..077f88bf --- /dev/null +++ b/daweb/react/formulare-efekty/shrnuti.md @@ -0,0 +1,7 @@ +## Shrnutí + +Po této lekci byste měli vědět a znát + +- co to je obousměrný data binding a jak propojit stav s obsahem políčka ve formuláři, +- jak v Reactu vytvořit jednoduchý efekt a načíst pomocí něj data z API, +- jak používat pokročilejší efekty se závislostmi. diff --git a/daweb/react/formulare-efekty/specializovane-efekty.md b/daweb/react/formulare-efekty/specializovane-efekty.md deleted file mode 100644 index 5c43a245..00000000 --- a/daweb/react/formulare-efekty/specializovane-efekty.md +++ /dev/null @@ -1,19 +0,0 @@ -## Specializované efekty - -Zatím jsme viděli efekty, které se spouštějí pouze jednou, tedy ve chvíli, kdy se komponenta poprvé objeví na stránce. Občas však potřebujeme efekt, který se spustí pokaždé, když se změní nějaká stavová proměnná nebo prop. Takový efekt vyrobíme tak, že do hranatých závorek napíšeme stavovou proměnnou nebo prop, na kterou má efekt reagovat. - -```js -const Komponenta = () => { - const [datum, setDatum] = useState('2022-05-14'); - - useEffect(() => { - console.log(`Hodnota stavové proměnné datum je ${datum}.`); - }, [datum]); - - // … -}; -``` - -Tato technika se nám hodí nejčastějí ve chvíli, kdy chceme stáhnout nějaká data z API ve chvíli, kdy komponenta změní svůj stav. - -V [Codesandboxu zde](https://codesandbox.io/s/da-web-svatky-v-den-xuj8oc?file=/src/App.jsx) si můžeš prohlédnout komponentu, která zobrazuje, kdo má svátek v den, který si zvolí uživatel. From 16388a5f4c70a39c61764f4f46c1dc48659ced57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Podlouck=C3=BD?= Date: Fri, 3 Nov 2023 09:07:38 +0100 Subject: [PATCH 2/2] =?UTF-8?q?Dopln=C4=9Bn=C3=AD=20popisk=C5=AF=20cvi?= =?UTF-8?q?=C4=8Den=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- daweb/react/formulare-efekty/cvlekce/vyber-zeme/exercise.md | 2 ++ .../formulare-efekty/cvlekce/zasilani-newsletteru/exercise.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/daweb/react/formulare-efekty/cvlekce/vyber-zeme/exercise.md b/daweb/react/formulare-efekty/cvlekce/vyber-zeme/exercise.md index 8809cb21..2d1a7991 100644 --- a/daweb/react/formulare-efekty/cvlekce/vyber-zeme/exercise.md +++ b/daweb/react/formulare-efekty/cvlekce/vyber-zeme/exercise.md @@ -1,6 +1,8 @@ --- title: Výběr země +lead: Přidejte do formuláře rozbalovací nabídku pro výběr země. demand: 2 +solutionAccess: lock --- ::fig[ukázka řešení]{src=assets/ukazka-reseni.gif} diff --git a/daweb/react/formulare-efekty/cvlekce/zasilani-newsletteru/exercise.md b/daweb/react/formulare-efekty/cvlekce/zasilani-newsletteru/exercise.md index f00baa57..8308ce35 100644 --- a/daweb/react/formulare-efekty/cvlekce/zasilani-newsletteru/exercise.md +++ b/daweb/react/formulare-efekty/cvlekce/zasilani-newsletteru/exercise.md @@ -1,6 +1,8 @@ --- title: Zasílání newsletteru +lead: Přidejte do formuláře zaškrtávací políčko pro zasílání novinek. demand: 3 +solutionAccess: lock --- ::fig[ukázka řešení]{src=assets/ukazka-reseni.gif}