Díky tomu, že jsem se v minulé lekci naučili pracovat se stavem, otvírají se nám v Reactu mnohé nové možnosti.
¶Formulářové prvky
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 o uživatele. V čístém JavaScritpu jsme zvyklí získávat hodnoty z těchto prvků tak, že je vybereme pomocí querySelector
a použijme například vlastnost value
.
const inputElm = document.querySelector('input');
const value = inputElm.value;
V Reactu však k DOM elementům na stránce přístup nemáme. Hodnotu uvnitř textového políčka se tak musíme uložit do stavu.
Představme si jednoduchou komponentu, kde uživatel zadá svůj věk.
const AgeField = () => {
return (
<label>
Zadej svůj věk:
<input type="text" />
</label>
);
};
Hodnotu uvnitř elementu input
si chceme uložit do stavu pokaždé, když dojde k její změně. Vytvoříme si proto stav age
a budeme jej měnit v reakci na událost onChange
.
const AgeField = () => {
const [age, setAge] = useState(null);
return (
<label>
Zadej svůj věk:
<input type="text" onChange={(e) => setAge(e.target.value)} />
</label>
);
};
Data binding
One-way (jednosměrný), two-way (obousměrný).
¶Cvičení: Formulářové prvky
¶Registrace
-
Založte si novou React aplikaci podle klasického starteru
-
Vytvořte komponentu
App
s jednoduchým textovým políčkem dle následujícího vzoru.const App = () => { const handleSubmit = (e) => { e.preventDefault(); }; return ( <form onSubmit={handleSubmit}> <label> Uživatelské jméno: <input type="text" /> </label> <button type="submit">Registrovat</button> </form> ); };
-
Na políčko přidejte událost
onChange
. V reakci na událost do konzole vypište obsah políčka pomocí vlastnostitarget.value
. Vyzkoušejte, že když do políčka píšete, v konzoli vidíte každou změnu jeho hodnoty. -
Uvnitř komponenty
App
vytvořte stavuserName
s výchozí hodnotou prázdný řetězec. Vytvořte obousměrný (two-way) data binding mezi textovým políčkem a stavemuserName
. -
V reakci na událost
onSubmit
do konzole vypište jméno uživatele uložené ve stavuuserName
. -
Na stránku přidejte
div
, který bude vidět pouze pokud ve stavuuserName
bude jméno a nikoliv prázdný řetězec. Obsahem prvku by měla být zprávaRegistrován nový uživatel jaroslav
Za jméno jaroslav dosaďte obsah stavu
userName
. -
Pokud je ve stavu
userName
uložen prádný řetězec, zobrazte ve vašemdivu
zprávu ve smysluUživatelské jméno je povinný údaj
-
Vzpomeňte si na vlastnost
disabled
a zařiďte, aby registrační tlačítko bylo dostupné pouze v případě, že ve stavuuserName
není prázdný řetězec.
¶Výběr země
Pokračujte v předchozím cvičení.
-
Přidejte do vašeho formuláře rozbalovací nabídku
select
, která bude sloužit k výběru země, ze které uživatel pochází.<label> Země původu: <select> <option value="Chorvatsko">Chorvatsko</option> <option value="Česká republika">Česká republika</option> <option value="Polsko">Polsko</option> <option value="Slovenská republika">Slovenská republika</option> </select> </label>
-
Vytvořte stav
country
, který bude sloužit k uložení hodnoty z vaší nabídky. Výchozí hodnotu stavu nastavte naČeská republika
. -
Pomocí události
onChange
zařiďte one-way data binding mezi nabídkouselect
a stavemcountry
. -
Zařiďte two-way data binding mezi nabídkou
select
a stavemcountry
tak, aby nabídka zobrazovala výchozí hodnotu uloženou ve stavu. -
Zprávu po úspěšné registraci změňte na
Registrován nový uživatel jaroslav ze země Polsko
Ve zprávě zobrazte zemi, kteoru si uživatel při registraci vybral.
¶Podmínky registrace
Pokračujte v předchozím cvičení.
- Přidejte do vašeho formuláře zaškrtávací políčko označené textem
Souhlasím s obchodními podmínkami
- Zařiďte, aby se uživatel mohl registrovat pouze v případě, že zaškrtnul souhlas s obdchodními podmínkami.
¶Efekty
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é efekty 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.
import React from 'react';
import { render } from 'react-dom';
import './index.html';
const App = () => {
return (
<>
<h1>Svátky</h1>
<div className="nameday">Svátek má Jiří</div>
</>
);
};
render(<App />, document.querySelector('#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.
import React, { useEffect } from 'react';
import { render } from 'react-dom';
import './index.html';
const App = () => {
useEffect(() => console.log('jsem tady'), []);
return (
<>
<h1>Svátky</h1>
<div className="nameday">Svátek má Jiří</div>
</>
);
};
render(<App />, document.querySelector('#app'));
Funkce useEffect
má dva parametry. Prvním je funkce, která se má zavolat a druhý parametr říká, za jakých okolností se má naše funkce volat. Prázdné pole []
znamená, že se efekt spustí pouze ve chvíli, kdy se komponenta poprvé objeví na stránce.
¶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.
Naše poslední aplikace zatím zobrazovala, že svátek má Jiří. To je však pravda pouze jeden den v roce. Pojďme aplikace vylepšit tak, aby si stáhla aktuální jméno z API.
import React, { useState, useEffect } from 'react';
import { render } from 'react-dom';
import './index.html';
const App = () => {
const [name, setName] = useState('');
useEffect(() => {
fetch('https://api.abalin.net/today?country=cz')
.then((resp) => resp.json())
.then((json) => setName(json.data.namedays.cz)
}, []);
return (
<>
<h1>Svátky</h1>
<div className="nameday">Svátek má {name}</div>
</>
);
};
render(<App />, document.querySelector('#app'));
V tomto případě jsme si do stavu ukládali pouze obyčejný řetězec. Naše data však budou často zobrazovat seznamy, takže budeme chtít mít ve stavu uložené nějaké pole.
http://worldtimeapi.org/api/timezone
¶Cvičení: Efekty a volání API
¶Pražský čas
-
Založte si novou React aplikaci podle klasického starteru
-
Založte komponentu
App
a uvnitř vytvořte jednoduchý efekt, který se spustí pří prvním zobrazení komponenty. Uvnitř tohoto efektu zavolejte funkcialert
a zobrazte vyskakovcí okno s nějakou zprávou. -
Přidejte do vaší komponenty stav
datetime
, jehož výchozí hodnota bude prázdný řetězec. Ve vašem efektu smažte voláníalert
a uložte do stavu nějaký čas jako řetězec ve formátu'2020-11-13T22:46';
Zobrazte váš čas někde na stránce a vyzkoušejte, že váš efekt správně nastaví stav při prvním zobrazení komponenty.
-
Upravte váš efekt tak, aby pomocí volání
fetch
získal aktuální datum a čas pro časovou zónuEurope/Prague
. Hodnotu získáte na API endpointuhttp://worldtimeapi.org/api/timezone/Europe/Prague
pod položkou
datetime
. Získanou hodnotu uložte do stavu a vyzkoušejte, že vaše aplikace funguje.
¶Výběr zóny
Pokračujte v předchozím příkladu.
- Vložte do stránky formulář, ze kterého si uživatel může vybrat časovou zónu. Uvnitř formuláře použijte následující
select
.<select> <option value="America/New_York">New York</option> <option value="Europe/London">Londýn</option> <option value="Europe/Moscow">Moskva</option> <option value="Europe/Prague">Praha</option> <option value="Asia/Hong_Kong">Hong Kong</option> <option value="Asia/Jerusalem">Jeruzalém</option> </select>
- Vytvořte stav
timezone
a funkcihandleTimezoneChange
, která propojí stav s hodnotou uvnitř prvkuselect
. Jako výchozí hodnotu pro tento stav zvolte Europe/Prague. - Zařiďte, aby se váš efekt volal při každé změně stavu
timezone
. Uvnitř efektu zkunstruujte URL pro váš dotaz tak, aby server poslal data pro uživatelem vybranou časovou zónu. - Vaše aplikace by měla fungovat tak, že když uživatel vybere z nabídky časovou zónu, rovnou se mu na stránce ukáže aktuální čas v této zóně.