IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

6. diel - Hooky v React - useCallback() a useMemo()

V predchádzajúcej lekcii, Základy štylovania aplikácie pomocou Material UI v Reactu , sme sa dozvedeli, ako pridať aplikáciu v React štýly pomocou knižnice Material UI a zoznámili sme sa s komponentmi Container, Grid, Typography a Button.

V tomto tutoriále pokročilého Reactu budeme pokračovať v téme hookov. Pozrieme sa na dva hooky slúžiace na cachovanie dát medzi renderovaním v React aplikácii. Konkrétne to budú hooky useCallback() a useMemo().

Hook useCallback()

Tento hook slúži na optimalizáciu výkonu komponentov. Umožňuje vytvoriť a uchovať v pamäti referenciu na funkciu tak, aby sa táto funkcia znovu vytvárala iba keď sa zmení konkrétne závislosti. React pri použití useCallback() funkciu iba vracia, nevolá ju. Hook je užitočný predovšetkým v situáciách, kde chceme zabrániť zbytočnému vytváraniu nových funkcií pri každom vykreslení komponentu.

Syntax hooku useCallback() vyzerá takto:

Kód si popíšeme:

  • memoizedFunction je do premennej uložená funkcia, ktorá bude memoizovaná a vrátená hookom useCallback(),
  • ako prvý argument hook prijíma funkciu, ktorá má byť memoizovaná,
  • druhým argumentom je pole závislostí, ktoré obsahuje premenné, od ktorých závisí daná funkcia. Funkcia sa vytvorí znovu iba ak sa niektorá z týchto premenných zmení.
Kedy použiť useCallback()

Typickou situáciou pre použitie useCallback() je, keď odovzdávame funkciu ako prop (vlastnosť) do komponentu, ktorý je optimalizovaný pomocou funkcie memo(). Pomocou memo() zamedzujeme prekresľovaniu komponentu v prípade, že jej props zostávajú rovnaké.

V JavaScripte však funkcia vždy vytvára novú funkciu. Preto funkcia posúvaná pomocou props do komponentu bude pri každom renderovaní považovaná za funkciu novú, aj keď sa nijako nezmení. Optimalizácia iba pomocou memo() v tomto prípade nebude fungovať, pokiaľ posúvanú funkciu neobalíme hookom useCallback(). Najlepšie bude ukázať si to na konkrétnom príklade:)

Funkcia memo() a hook useMemo sú dve odlišné veci. Funkcia memo() slúži na memoizáciu celého komponentu. Hook useMemo() slúži na memoizáciu výsledku výpočtu alebo hodnoty v rámci komponentu.

Použitie useCallback() v aplikácii

Budeme vychádzať z aplikácie z lekcie Hooky v React - useState(), useEffect() a useRef().

V nej si tiež stiahneme projekt, ktorý teraz spoločne upravíme. Výsledná aplikácia bude vyzerať takto:

Hotová aplikácia - Pokročilý React

Príprava projektu

Stiahnutý projekt si otvoríme v preferovanom editore kódu. V termináli si spustíme príkaz na inštaláciu modulov a projekt spustíme na lokálnom serveri:

Element input už nebudeme potrebovať, preto v komponente MainCompChild.js zmažeme premennú inputRef a hook useEffect().

Zmažeme aj input z vykresľovanej časti.

Potom pridáme novú funkcionalitu. Importujeme si rovno všetky hooky, ktoré využijeme:

Hneď pod console.log potom do funkcie MainCompChild() vložíme kód:

Vytvoríme stav, kde si ukladáme číslo, od ktorého pomocou funkcie decrementChildCount() odčítame jednotku. Funkcia sa neskôr spustí po kliknutí na tlačidlo.

V časti za return potom pod nadpisom <h3> vypíšeme aktuálny stav premennej childCount:

Pridanie komponentu Button

Teraz si do aplikácie pridáme vlastný komponent na vykreslenie tlačidla. Tento komponent bude prijímať ako prop funkciu, ktorá sa spustí po kliknutí na tlačidlo.

Vytvoríme si zložku UI/ v adresári src av nej súbor Button.js s nasledujúcim kódom:

Po každom renderovaní tlačidla si vypíšeme do konzoly, že render prebehol ao ktoré tlačidlo ide. Tlačidlo si exportujeme pomocou funkcie memo(). To nám zaistí, že sa prekreslí iba ak sa zmení jeho prop.

Teraz tlačidlo použijeme v súbore MainCompChild.js. Najprv si ho importujeme:

Pod vykreslenie odseku <p> s počtom vložíme kód:

Aplikácia teraz vyzerá nasledovne:

Tlačidlo už máme - Pokročilý React
Implementácia hooku useCallback()

Naše tlačidlo je exportované pomocou funkcie memo(). Očakávame preto, že sa opätovne vykreslí iba vtedy, ak sa zmení jeho props.

Keď si však otvoríme vývojárske nástroje, premažeme konzolu a klikneme na tlačidlo Plus v hlavnom komponente alebo na tlačidlo Mínus v detskom komponente, vidíme, že sa zakaždým znovu vykresľuje tlačidlo s mínusom, ktoré je urobené cez náš vlastný <Button> komponent. V konzole vidíme pri každom vykreslení tlačidla vypísaný nadpis tlacitko render -.

Je to preto, že React opakovane pri každom rendere vytvára funkciu decrementChildCount(), ktorú tlačidlo v detskom komponente prijíma ako prop. Preto sa tlačidlo aj napriek použitiu memo() opätovne vykresľuje.

To opravíme použitím hooku useCallback(), do ktorého obalíme funkciu decrementChildCount() v súbore MyCompChild.js. Funkciu nahradíme kódom:

Pole závislostí je prázdne a funkcia preto zostáva zakaždým rovnaká. Keď sa teraz pozrieme do konzoly vo vývojárskych nástrojoch a klikneme na Plus alebo Mínus, vidíme, že tlačidlo s mínusom sa vykresľuje iba pri prvotnom renderovaní, potom už nie.

Hook useMemo()

Hook useMemo() slúži na memoizáciu výpočtov a hodnôt, a tým pomáha optimalizovať výkon komponentov. Memoizácia znamená uchovanie výsledku výpočtu a jeho opätovné použitie, pokiaľ sa vstupná závislosť nezmení. Koncept už poznáme z hooku useCallback(). Len tentoraz neukladáme celú funkciu, ale iba jej výsledok.

Syntax hooku vyzerá takto:

Pozrime sa na kód bližšie:

  • memoizedValue je uložený výsledok výpočtu alebo transformácie dát, ktorý bude memoizovaný a vrátený hookom useMemo(),
  • ako prvý argument hook prijíma výpočet alebo transformáciu dát, ktorá má byť memoizovaná,
  • ako druhý argument potom vložíme pole závislostí, ktoré obsahuje premenné, od ktorých závisí náš výpočet. Ak sa niektorá z týchto premenných zmení, výpočet sa vykoná znova. Inak sa vráti uložená hodnota z predošlého renderovania.
Kedy použiť useMemo()

Do hooku useMemo() sa obvykle ukladajú náročné kalkulácie, ktorých závislosti sa menia iba ojedinele. Inak platí to, čo pre useCallback(). Hook oceníme, pokiaľ je hodnota posúvaná v prop komponente obalenej funkciou memo(), alebo je hodnota využitá ako závislosť iného hooku.

Poďme si teraz ukázať konkrétny príklad použitia hooku useMemo().

Použitie useMemo() v aplikácii

Budeme pokračovať v práci s našou aplikáciou. Otvoríme si súbor MainCompChild.js. Pod funkciu decrementChildCount() vložíme novú funkciu, ktorú potom rovno zavoláme pre childCount a výsledok uložíme do premennej doubleWithoutMemo:

Pod tlačidlo Mínus potom vypíšeme výsledok:

Otvoríme si vývojárske nástroje. V konzole po kliknutí na tlačidlo Plus vidíme, že prebehne výpočet zdvojnásobenia premennej childCount av konzole sa vypíše text krát dva. To je však zbytočné, pretože sa táto premenná nemení.

Pomocou hooku useMemo() teraz docielime, nech sa výpočet opakovane vykonal iba pri zmene stavu childCount, teda po kliknutí na tlačidlo Mínus. Premennú doubleWithoutMemo nahradím kódom:

A k Počet krát dva vykreslíme hodnotu premennej memoizedVal:

Teraz sme v situácii, že je naša funkcia countDouble() závislosťou hooku useMemo(). Pre správnu funkcionalitu ju preto ešte zabalíme do hooku useCallback(), nech sa závislosť hooku useMemo() nemení pri každom renderovaní.

Funkciu countDouble() nahradíme kódom:

Hotovo:) V konzole vývojárskych nástrojov teraz po kliknutí na Plus vidíme, že výpočet zdvojnásobenia premennej childCount už zbytočne neprebieha. Dosiahli sme to vďaka využitiu kombinácie hookov useCallback() a useMemo().

V nasledujúcej lekcii, Načítanie dát na pozadí , si vyskúšame použitie komponentu Suspense v kombinácii s funkciou lazy(). To nám pomôže užívateľovi komunikovať, že dáta ešte nie sú všetky načítané a pripravené na zobrazenie.


 

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é 6x (321.49 kB)
Aplikácia je vrátane zdrojových kódov v jazyku JavaScript

 

Predchádzajúci článok
Základy štylovania aplikácie pomocou Material UI v Reactu
Všetky články v sekcii
Pokročilý React
Preskočiť článok
(neodporúčame)
Načítanie dát na pozadí
Článok pre vás napísala Laura Baluchová
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Aktivity