5. diel - Stavy v React a hook useState()
V minulej lekcii, Vlastnosti v React - Props, sme si vysvetlili koncept vlastností props. Ukázali sme si, ako sa vlastnosti zadávajú v HTML kóde, načítajú v komponente a deštrukturalizujú.
V tomto React tutoriále sa naučíme obsluhovať stavy našej aplikácie,
objavíme React hooks a naučíme sa používať hook
useState()
.
Stavy v React a hooks
Stav React komponentov (state) je podobný vlastnostiam, ale používa sa iba vo vnútri komponentu a môže sa meniť. V podstate sa jedná o privátne dáta komponentu iba pre vnútorné použitie.
Stavy sú inými slovami premenné, ktoré sa v React aplikácii menia a my na ich zmenu chceme nejako reagovať.
Hooks
Ako sme už načrtli v úvodnej lekcii, k funkcionalitám Reactu sa
dostávame pomocou hooks. Hook (v preklade háčik) nie je nič iné než
funkcia, ktorá nám sprístupní nejakú funkcionalitu z
React. „Zasekneme“ sa háčikom do Reactu a „ťaháme“ si, čo
potrebujeme. Na prácu s vnútorným stavom komponentu budeme používať hook
(funkciu) useState()
.
Práca s hookom useState()
Použitie useState()
prebieha v troch krokoch:
1. Hook musíme najprv naimportovať, aby sme mali funkciu
useState()
dostupnú:
import React, { useState } from 'react';
2. Zavoláme useState()
a odovzdáme mu predvolenú
hodnotu stavu (tá môže byť aj null
):
useState(null);
3. Funkcia useState()
nám vráti pole s dvoma
premennými, kde prvá premenná obsahuje súčasný stav a
druhá premenná je funkcia pre zmenu tohto stavu:
const [state, setState] = useState(null);
Premenná state
teraz obsahuje stav s hodnotou
null
. A pomocou funkcie setState()
tento stav môžeme
meniť. Rovnakým spôsobom si môžeme v komponente vytvoriť ďalšie stavy.
Poďme si tento jednoduchý mechanizmus vyskúšať na príklade.
Vytvorenie projektu - Tlačidlo s poštovou schránkou
Na vyskúšanie stavov si vytvoríme projekt, v ktorom bude tlačidlo s poštovou schránkou. Akonáhle naň klikneme, schránka sa otvorí a po opätovnom kliknutí sa zase zavrie. Na reprezentáciu stavu schránky použijeme stav.
V prieskumníku Windows klikneme pravým tlačidlom myši na náš priečinok s projektmi za držania klávesu Shift. V kontextovom menu vyberieme otvorenie nového okna Terminal/PowerShell:
Pomocou nasledujúceho príkazu vytvoríme nový React projekt s názvom
mailbox
:
Windows PowerShell PS C:\Users\sdrac\Dropbox> npx create-react-app@^5.0.1 mailbox
Pomocou príkazu cd
sa presunieme do priečinka projektu:
Windows PowerShell PS C:\Users\sdrac\Dropbox> cd mailbox
A projekt spustíme príkazom:
Windows PowerShell PS C:\Users\sdrac\Dropbox\mailbox> npm start
Následne sa presunieme opäť do prieskumníka Windows, klikneme na
priečinok mailbox/
pravým tlačidlom myši a otvoríme ho vo VS
Code pomocou ponuky Otvoriť v Code.
Komponent MailboxButton
V priečinku src/
si vytvoríme nový súbor
MailboxButton.js
. Do neho vložíme nasledujúci základ
komponentu:
function MailboxButton() { return <button>📪</button>; } export default MailboxButton;
Súbor uložíme. Pre obrázok poštovej schránky sme
použili emoji, aby sme ho nemuseli sťahovať 🤩 Trochu si ho ešte
zväčšíme pridaním CSS štýlu do App.css
:
button { margin-top: 5rem; font-size: 10rem; }
Súbor opäť uložíme.
Vloženie komponentu do
App.js
Z komponentu App.js
odstránime nepotrebné súčasti
východiskového React projektu. Ďalej naimportujeme náš komponent
MailboxButton
a vložíme ho do HTML kódu komponentu
App
:
import './App.css'; import MailboxButton from './MailboxButton'; function App() { return ( <div className="App"> <MailboxButton /> </div> ); } export default App;
Súbor uložíme a môžeme sa pozrieť do prehliadača, kde uvidíme naše tlačidlo:
Pridanie stavu
Do komponentu si teraz naimportujeme hook useState()
a jeho
zavolaním si definujeme stav pre to, či je poštová schránka plná:
import React, { useState } from 'react'; function MailboxButton() { const [full, setFull] = useState(false); // Creation of state full return ( <button> {full ? '📬' : '📪'} </button> ); } export default MailboxButton;
Pomocou funkcie useState()
sme vytvorili dve premenné:
full
- Stav určujúci, či je poštová schránka plná.setFull()
- Setter funkcie pre zmenu stavu poštovej schránky.
Pri volaní useState()
sme zároveň nastavili, že predvolený
stav je false
.
Rovnako sme upravili vykreslenie tlačidla. To je teraz rozpísané na viac
riadkov, čo spôsobilo, že sme celé JSX museli vložiť do zátvoriek
()
. Do tlačidla vykresľujeme buď emoji plnej poštovej schránky
📬 alebo prázdne 📪 podľa toho, či je stav full
true
alebo false
. Použili sme ternárny operátor v
JSX, kedy sa pri pravdivej hodnote premennej vykreslí časť za otáznikom
?
a pri nepravdivej časť za dvojbodkou :
. Určite ho
poznáte aj z JavaScriptu.
V prehliadači si môžeme skontrolovať, že aplikácia robí stále to
isté. Môžete si skúsiť zmeniť predvolený stav v parametri funkcie
useState()
z false
na true
, čím sa
zmení obrázok na schránke:
Zmena stavu
Teraz elementu <button>
obslúžime udalosť
onClick
. K tomu si vytvoríme funkciu vo vnútri komponentu s
názvom začínajúcim na handle*
, v našom prípade
handleClick()
:
import React, { useState } from 'react'; function MailboxButton() { const [full, setFull] = useState(false); function handleClick() { setFull(!full); } return ( <button onClick={handleClick}> {full ? '📬' : '📪'} </button> ); } export default MailboxButton;
Vo funkcii nastavíme pomocou setteru setFull()
novú hodnotu
stavu, a to na negáciu stavu pôvodného, teda !full
. Funkciu
tiež nastavíme do atribútu onClick
elementu
<button>
. Súbor uložíme a môžeme si v prehliadači
vyskúšať, že schránka po kliknutí naozaj mení svoj stav a zobrazuje iný
emoji:
Vzhľad emoji sa bude líšiť podľa vášho operačného systému.
Prečo nepoužijeme premenné?
Možno vám napadlo, prečo používať nejaké stavy, keď môžeme
vytvoriť len obyčajnú true
/false
premennú, ktorá
by stav poštovej schránky určovala? Stavy majú navyše vnútornú
logiku, ktorú potom využíva vykresľovacie jadro
React. Používaním stavov sa pri ich zmene daná súčasť komponentu sama
prekreslí bez toho, aby sme sa o to museli starať. Všimnite si, že sme pri
kliknutí na tlačidlo jeho obsah inak nemenili, zmenili sme len stav. To by s
obyčajnou premennou nefungovalo.
Alternatívne zápisy
Nakoniec si opäť ukážme niekoľko alternatívnych zápisov, aby ste vedeli čítať ďalšie aplikácie.
Použitie arrow funkcie
Na obsluhu udalosti môžeme použiť arrow funkciu, čím sa vyhneme deklarácii handler funkcie:
import React, { useState } from 'react'; function MailboxButton() { const [full, setFull] = useState(false); return ( <button onClick={() => setFull(!full)}> {full ? '📬' : '📪'} </button> ); } export default MailboxButton;
Používanie arrow funkcií pri renderovaní v React spôsobí, že sa pri každom prekreslení vytvorí nová funkcia. Pri zložitejších projektoch môže byť preto z hľadiska výkonu lepšie použiť klasickú handler funkciu.
Čo ale nefunguje je zavolanie setteru priamo v parametri bez arrow funkcie:
import React, { useState } from 'react'; function MailboxButton() { const [full, setFull] = useState(false); return ( <button onClick={setFull(!full)}> {full ? '📬' : '📪'} </button> ); } export default MailboxButton;
Tým by sme totiž cez JSX setter rovno zavolali (bez kliknutia na tlačidlo). A React má ochranu pred tým, aby zmeny stavov prebiehali bezprostredne za sebou, čím sa môže aplikácia zacykliť. Aplikácia nám potom spadne s chybou: "Too many re-renders. React limits the number of renders to prevent an infinite loop":
Rovnakú chybu by sme dostali, keby sme sa snažili napr. nastaviť stav priamo v metóde komponentu, teda aby sa hneď po nastavení zas zmenil:
import React, { useState } from 'react'; function MailboxButton() { const [full, setFull] = useState(false); setFull(true); // This line will cause an error return ( <button onClick={() => setFull(!full)}> {full ? '📬' : '📪'} </button> ); } export default MailboxButton;
Dve najdôležitejšie súčasti React aplikácií, vlastnosti a stavy, máme týmto prebrané
V nasledujúcom cvičení, Riešené úlohy k 1.-5. lekcii React, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 3x (177.06 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript