IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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

React hooks - Základy React

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/Power­Shell:

Kontextové menu pre spustenie príkazového riadka - Základy React

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:

React App
localhost:3000

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:

React App
localhost:3000

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:

Poštová schránka - Základy React

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":

Too many re-renders v React - Základy React

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

 

Predchádzajúci článok
Vlastnosti v React - Props
Všetky články v sekcii
Základy React
Preskočiť článok
(neodporúčame)
Riešené úlohy k 1.-5. lekcii React
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
4 hlasov
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity