7. diel - Kalkulačka v React - Tvorba komponentov
V minulej lekcii, Kalkulačka v React - Projekt a rozdelenie na komponenty, sme vytvorili základ pre prvú jednoduchú kalkulačku za použitia knižnice React.
V tomto React tutoriále si postupne vytvoríme komponenty na zadanie čísla, vypísanie výsledku a pre formulár kalkulačky.
Komponent pre zadávanie
čísla – NumberInput.jsx
V novom priečinku src/calculator/ vytvoríme súbor
NumberInput.jsx, ktorý bude naším komponentom pre
číselný vstup:

Bude teda vykresľovať elementy <input>,
<label> a obsluhovať udalosť zmeny čísla vo vstupnom
poli. Kód komponentu bude nasledovný:
function NumberInput({ name, label, value, onChange }) { return ( <label htmlFor={name}> {label} <input id={name} type="number" name={name} required onChange={(e) => onChange(parseFloat(e.target.value))} value={isFinite(value) ? value : ""} /> </label> ); } export default NumberInput;
Výhodou tohto komponentu je, že si generuje aj <label> a
nastavuje atribúty, ktoré by sme inak museli nastavovať pre každé zadanie
čísla v aplikácii znova.
Hneď v deklarácii funkcie komponentu sme si deštrukturalizovali vlastnosti. Tie komponentu nastavíme, až ho budeme vkladať do komponentu kalkulačky. Sú to:
name– názov číselného vstupu,label– text popisku číselného vstupu,value– zadaná hodnota,onChange– funkcia, ktorú komponent zavolá pri zmene svojej číselnej hodnoty.
Ďalej vraciame výsledný HTML kód komponentu, ktorý je rozpísaný na
viac riadkov a preto je zapísaný v zátvorkách (). Tiež si
všimnite, že je celý HTML kód uzavretý v jedinom HTML elemente (tu
<label>), inak by totiž JSX zápis nebol validný.
Možno ste si tiež všimli, že namiesto atribútu for pre
<label> používame htmlFor. To preto, že keď
mixujeme HTML priamo do JavaScriptu, nesmieme zabudnúť, že for
je v JS rezervované ako kľúčové slovo pre cyklus. JSX teda namiesto neho
zavádza náhradu, ktorá sa do výsledného HTML preloží správne ako HTML
atribút for. Ten, ako vieme, určuje, ku ktorému formulárovému
prvku je štítok (<label>) viazaný. Tu by sme ho ani
zadávať nemuseli, pretože vstupné pole je vložené priamo v labeli, ale
ukázali sme si, ako sa v JSX zapisuje.
Reagovanie na zmenu hodnoty
Pre získanie používateľom zadanej hodnoty do vstupného poľa
<input> je potrebné reagovať na udalosť
onChange. V Reacte obsluhujeme udalosti úplne rovnako ako v
čistom JavaScripte. Do atribútu udalosti HTML
elementu (onSubmit, onChange a pod.) jednoducho
nastavíme funkciu, ktorá sa zavolá, keď udalosť nastane.
Atribútu onChange vstupného poľa <input>
preto predávame arrow funkciu s jedným parametrom e, ktorý
obsahuje informáciu o vykonanej zmene. V tejto funkcii voláme našu funkciu
onChange() predanú ako vlastnosť komponentu
NumberInput. Hodnota e.target.value je potom hodnota
zadaná používateľom vo vstupnom poli. Táto hodnota je však reťazec, preto
ju pred predaním do našej funkcie onChange() najprv parsujeme na
číslo.
Namiesto deklarácie arrow funkcie by sme rovnako tak mohli
deklarovať aj handler funkciu pomocou kľúčového slova
function. Keďže v handleru potrebujeme zavolať len našu funkciu
onChange(), používame kratšiu variantu.
Vstupnému poľu nakoniec ešte nastavujeme aktuálnu hodnotu
value predanú nášmu komponentu NumberInput.
Funkciou isFinite() kontrolujeme, či ide o validné konečné
číslo, ktoré je možné vstupnému poľu nastaviť. Inak nastavujeme prázdny
reťazec.
Komponent pre zobrazenie
výsledku – Result.jsx
V priečinku src/calculator/ vytvoríme ďalší súbor,
Result.jsx, ktorý bude komponentom pre
výsledok:

Výsledok si zobrazíme jednoducho v elemente <div>. Kód
komponentu bude nasledovný:
function Result({ value }) { if (value !== null) return <div className="Result">Result: {value}</div>; return null; } export default Result;
Výsledok má len jednu vlastnosť a tou je vypisovaná hodnota.
Keďže ďalej budeme chcieť na výsledok aplikovať CSS, pridáme mu HTML
atribút class. Avšak opäť sa jedná v JS o rezervované slovo,
takže v JSX namiesto toho použijeme atribút className, ktorý sa
potom vyrenderuje ako atribút class. Ten sa tiež používa v
súvislosti s označením samotných komponentov, a preto za účelom
prehľadnosti zvolíme rovnaký názov CSS triedy, ako je názov komponentu.
Ďalej stojí za povšimnutie, že v komponente vraciame null,
pokiaľ výsledok nie je zadaný a my nič nevyrenderujeme. Ak komponent nemá
nič vykresliť, mal by vracať null – predsa len nejakú hodnotu
vracať musí.
Komponent s
formulárom kalkulačky – CalculatorForm.jsx
Teraz, keď už máme príslušné súčasti, môžeme vytvoriť centrálny
komponent aplikácie – formulár CalculatorForm.jsx. Súbor
opäť vytvoríme do podpriečinka calculator/ v src/.
Formulár s kalkulačkou bude tvorený elementom <form>.
Ďalej bude obsahovať nami vyššie vytvorené komponenty a samozrejme
odosielacie tlačidlo typu submit, aby sa formulár dal
odoslať:

Kód komponentu bude nasledovný:
import NumberInput from "./NumberInput"; import Select from "react-select"; import Result from "./Result"; function CalculatorForm() { return ( <div> <form className="CalculatorForm"> <NumberInput name="a" label="First number:" /> <NumberInput name="b" label="Second number:" /> <Select options={[]} /> <input type="submit" value="Calculate" /> </form> <Result /> </div> ); } export default CalculatorForm;
Potrebné komponenty sme na začiatku súboru naimportovali.
Pri vykreslení formulára vidíme krásne a jednoduché zloženie React
aplikácie z komponentov, ktoré sme vytvorili pred chvíľou. Všimnite si, že
sme pri vložení našich komponentov do formulára nastavili niektoré ich
vlastnosti. Zvyšok vlastností, napr. hodnota čísel alebo výsledok, sa bude
nastavovať podľa stavov kalkulačky, ktoré pridáme ďalej v kurze. Vidíme
tu aj použitie komponentu <Select />, ktorý sme si pri
zakladaní projektu nainštalovali v rámci balíčka react-select.
Selectu sme nastavili jeho možnosti options zatiaľ na prázdne
pole [], možnosti na výber dodáme opäť neskôr v priebehu
kurzu.
Komponent celej aplikácie –
src/App.jsx
Nakoniec teda upravíme samotný komponent našej aplikácie. Odmažeme zbytočné zvyšky východiskovej React šablóny a vložíme sem náš formulár s kalkulačkou:
import CalculatorForm from "./calculator/CalculatorForm"; import "./App.css"; const title = "React calculator"; function App() { return ( <div className="App"> <h1>{title}</h1> <CalculatorForm /> </div> ); } export default App;
Opäť nič zložité. Jediná zaujímavá vec v kóde je nastavenie hodnoty
nadpisu cez konštantu pomocou syntaxe {}, a je to opäť veľmi
priamočiare.
A to je všetko. Keď si teraz spustíme aplikáciu, v prehliadači sa zobrazí zodpovedajúca HTML štruktúra:

V budúcej lekcii, Kalkulačka v React - Utility funkcie a stavy, sa naučíme používať utility funkcie a
definujeme stavy našej aplikácie pomocou React hooku
useState().
Mal si s čímkoľvek problém? Zdrojový kód vzorovej aplikácie je k stiahnutiu každých pár lekcií. Zatiaľ pokračuj ďalej, a potom si svoju aplikáciu porovnaj so vzorom a ľahko opráv.
