Hook pro optimalizaci výkonu useMemo v Reactu
První hook pro optimalizaci
výkonu, který se podíváme
- je useMemo.
Tento hook pomáhá ukládat do mezipaměti výsledky náročných operací mezi okamžiky překreslování obrazovky a podle toho může pomoci zabránit zbytečným objemným výpočtům. Takové ukládání do mezipaměti se nazývá také memoizace.
Podívejme se, jak to funguje. Pojďme
vytvořit komponentu s tlačítkem a
nadpisem h3:
return (
<div>
<h3>Text</h3>
<button>click</button>
</div>
);
A nyní uděláme tak, aby po kliknutí
na nadpis se jeho barva měnila z oranžové
na zelenou a zpět. Pro začátek
vytvoříme stav isGreen:
const [isGreen, setIsGreen] = useState(false);
Přidejme do atributu style nadpisu
podmínku změny barvy nadpisu a
přidáme obsluhu kliknutí:
<h3 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? 'green' : 'orangered' }}
>Text</h3>
Nechť máme také nějakou hodnotu, která se bude zvyšovat po kliknutí na naše tlačítko o jedničku. Vytvoříme pro ni stav:
const [num, setNum] = useState(0);
Přidáme obsluhu kliknutí na tlačítko:
<button onClick={() => setNum(num + 1)}>
kliky
</button>
Nechť máme také nějakou funkci
square, která bude vracet
druhou mocninu hodnoty num. Výsledek
volání funkce budeme zapisovat do
proměnné result:
const result = square(num);
function square(num) {
return num * num;
}
Vypíšeme result v textu tlačítka:
<button onClick={() => setNum(num + 1)}>
kliky: {result}
</button>
Výsledkem jsme dostali následující:
po kliknutí na tlačítko se změní hodnota
num, která se pak umocní
na druhou, a po kliknutí na nadpis
se změní barva nadpisu.
Máme velmi malou komponentu, vše funguje rychle, i přesto, že po kliknutí na nadpis pro změnu jeho barvy se celá komponenta vykreslí znovu, podle toho dochází znovu i k výpočtům, které jsou vázány na tlačítko, a to i při tom, že jsme se ho nedotkli. A teď si představte, kdyby naše výpočty byly objemné a vše by se přepočítávalo znovu pokaždé.
Pojďme, trochu zatížit naši funkci, nyní bude chvíli přemýšlet. Tímto způsobem nasimulujeme dlouhé výpočty:
function square(num) {
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Prostě nic nedělej ...
}
return num * num;
}
Klikejme nyní na nadpis. Vychází to tak,
že nyní kvůli dlouhé práci funkce
square (a tlačítko jsme se nedotkli)
musíme celou věčnost čekat, aby u
nadpisu změnila barva!
Zde nám na pomoc přijde hook
useMemo. K tomu potřebujeme prvním
parametrem předat funkci, která vypočítá
hodnotu, kterou chceme uložit do mezipaměti,
tato funkce musí být čistá a nesmí
přijímat žádné parametry. A druhým
parametrem - závislosti v hranatých
závorkách, jinými slovy, všechny reaktivní
hodnoty, které se účastní v kódu
funkce. Tímto způsobem, do result
nyní napíšeme takovou konstrukci:
const result = useMemo(() => square(num), [num]);
Znovu klikejme na nadpis. Nyní,
pokud se nedotýkáme tlačítka s výpočty
a neměníme tímto způsobem hodnotu stavu
num, tak se nic nepřepočítává,
a React zobrazuje hodnotu uloženou v mezipaměti
v tlačítku, proto náš nadpis
rychle mění svou barvu.
Vytvořte komponentu App, umístěte
v ní odstavec. Vytvořte stav text
s počáteční hodnotou 'react',
nechť hodnota stavu se zobrazuje
jako text odstavce. Nechť po kliknutí
na odstavec, se mu na konec textu přidá
vykřičník.
Vytvořte ještě jeden stav num, s
počáteční hodnotou 0. Umístěte v
App ještě jeden odstavec. Udělejte tak,
aby při kliknutí na něj se num
zvýšila o 1.
A nyní přidejte do App funkci
triple, která jako
parametr přijímá num a
vrací jeho ztrojnásobenou hodnotu.
Vložte výsledek volání funkce
do proměnné result. Zobrazte
result jako text druhého
odstavce. Klikejte postupně na odstavce,
poznamenejte si, jak pomalu se přidávají
vykřičníky.
Opravte situaci, obalení pomalé
funkce triple do useMemo.