Huk useCallback za optimizacijo zmogljivosti v Reactu
V tej lekciji bomo obravnavali naslednji
huk za optimizacijo zmogljivosti
useCallback.
Huk useCallback je podoben API-ju useMemo,
razlika je v tem, da prvi
shrani vrednost med ponovnimi prikazi
zaslona, drugi pa - callback.
To nam omogoča, da ne znova zaženemo za vire zahtevnih
funkcij, ko to ni potrebno in se lahko
uporablja pri
posredovanju funkcije
v podrejene komponente.
Poglejmo si podrobneje s primerom.
Za začetek ustvarimo komponento App
in v njej pripravimo stanje num:
const [num, setNum] = useState(0);
Naj imamo gumb, ob kliku
na katerega se num poveča
za 1, in odstavek, v katerem
bomo prikazovali vrednost num:
return (
<div>
<button onClick={() => setNum(num + 1)}>klik</button>
<p>kliki: {num}</p>
</div>
);
Zdaj pa predpostavimo, da se v
App prikaže še nek seznam
z elementi, ki ga bomo dopolnjevali
ob pritisku drugega gumba. Za shranjevanje
elementov tega seznama bomo pripravili
stanje items:
const [items, setItems] = useState([]);
Nato napišimo funkcijo addItem
za njihovo dodajanje:
function addItem() {
setItems([...items, 'nov element']);
}
Zdaj pa napišimo kodo za prikaz
elementov seznama in jo premaknimo v podrejeno
komponento Items, ki bo prejela
kot propse polje elementov
in funkcijo za njihovo dodajanje. Ne pozabimo
dodati izpisa v konzolo, da bomo videli
kdaj se bo naš Items
ponovno prikazal:
function Items({ items, addItem }) {
const result = items.map((item, index) => {
return <p key={index}>{item}</p>;
});
console.log('Items render');
return (
<div>
<h3>Naši elementi</h3>
{result}
<button onClick={addItem}>dodaj element</button>
</div>
);
}
export default Items;
Postavimo Items na konec komponente
App in mu posredujmo polje
items in funkcijo za dodajanje
elementov addItem:
return (
<>
<div>
<button onClick={() => setNum(num + 1)}>klik</button>
<p>kliki: {num}</p>
<br />
</div>
<Items items={items} addItem={addItem} />
</>
);
Zdaj pa klikajmo na gumbe
in se prepričajmo, da
num narašča in
novi elementi se dodajajo v seznam.
Če odpremo konzolo, bomo videli, da
se naš seznam ponovno prikaže vsakič,
tudi če kliknemo na gumb,
ki povečuje num.
Če imamo majhen seznam, je vse
v redu, kaj pa če predvidevamo, da bo
obsežen in bo v njem še veliko drugega?
Ni težava - boste rekli, saj smo v prejšnji
lekciji obravnavali API memo,
da se ravno izognemo nepotrebnim ponovnim prikazom
komponente.
Torej ovijmo našo komponento
Items v memo in stvar rešena.
Mimogrede, to lahko storimo neposredno
pri izvozu Items:
export default memo(Items);
Ne pozabimo uvoziti memo:
import { memo } from 'react';
Zdaj pa odprimo konzolo in klikajmo
na gumbe. Vsi napori zaman!
Memorizirali smo komponento, a ob pritisku
na gumb 'klik' se komponenta
Items vseeno
ponovno prikaže vsakič.
Bistvo je v tem, da ko se nadrejena
komponenta ponovno prikaže, se njene funkcije
znova ustvarijo - to velja tudi za našo
funkcijo addItem, ki jo posredujemo v
Items.
Prav v tem trenutku nam bo pomagal huk
useCallback. Uporabimo
ga. Za začetek ga uvozimo v
App:
import { useCallback } from 'react';
Nato preoblikujemo preprosto deklaracijo funkcije
addItem v
Function Expression, podamo kot
prvi parameter za useCallback
našo funkcijo v obliki callbacka. Kot drugi
parameter v oglatih oklepajih podamo
odvisnosti - vse reaktivne spremenljivke,
ki sodelujejo v funkciji, v našem primeru
je to polje items:
const addItem = useCallback(() => {
setItems(() => [...items, 'Nov element']);
}, [items]);
Končano! Tako smo shranili funkcijo v predpomnilnik.
Ponovno kliknimo na gumbe in
vidimo, da se zdaj ob pritisku na gumb
'klik' naša podrejena komponenta ne
ponovno prikaže.
Ustvarite komponento App, postavite
v njo odstavek z besedilom. Pripravite
stanje z začetno vrednostjo 'besedilo'
in jo prikažite v odstavku. Naj ob kliku
na odstavek na konec besedila
doda klicaj.
Ustvarite podrejeno komponento Products,
v kateri boste imeli gumb za dodajanje
novega produkta. Postavite jo v App.
V nadrejeni komponenti ustvarite stanje
s poljem produktov in funkcijo dodajanja
novega produkta. Posredujte jih v
kot propse v podrejeno, prikažite v njej
posredovano polje v obliki seznama ul.
V Products izpišite v konzolo besedilo
'products render'.
Ovijte Products v memo.
Klikajte na odstavek in gumb. Prepričajte se,
da se ob kliku na odstavek podrejena komponenta
vseeno ponovno prikaže.
Shranite funkcijo za dodajanje
produktov v predpomnilnik, tako da jo ovijete v huk useCallback.
Klikajte na odstavek in gumb. Prepričajte se,
da se ob kliku na odstavek, se podrejena komponenta
več ne ponovno prikaže.