Huk za optimizaciju performansi useMemo u Reactu
Prvi huk za optimizaciju
performansi koji ćemo razmotriti
je useMemo.
Ovaj huk pomaže u keširanju rezultata resursno zahtevnih operacija između trenutaka ponovnog iscrtavanja ekrana i, shodno tome, može pomoći u izbegavanju nepotrebnih obimnih proračuna. Takvo keširanje se takođe naziva memorizacija.
Hajde da vidimo kako ovo funkcioniše. Kreirajmo
komponentu sa dugmetom i
naslovom h3:
return (
<div>
<h3>Tekst</h3>
<button>klik</button>
</div>
);
A sada, hajde da postavimo tako da klikom
na naslov njegova boja se menja iz narandžaste
u zelenu i obrnuto. Za početak,
definišimo stanje isGreen:
const [isGreen, setIsGreen] = useState(false);
Dodajmo u atribut style naslova
uslov za promenu boje i
dodajmo rukovalac klika:
<h3 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? 'green' : 'orangered' }}
>Tekst</h3>
Neka takođe postoji neka vrednost koja će se povećavati za jedan pri kliku na naše dugme. Definišimo stanje za nju:
const [num, setNum] = useState(0);
Dodajmo obradu klika na dugme:
<button onClick={() => setNum(num + 1)}>
klikovi
</button>
Neka takođe postoji neka funkcija
square koja će vraćati
kvadrat vrednosti num. Rezultat
poziva funkcije ćemo zapisati u
promenljivu result:
const result = square(num);
function square(num) {
return num * num;
}
Ispišimo result u tekstu dugmeta:
<button onClick={() => setNum(num + 1)}>
klikovi: {result}
</button>
Kao rezultat, dobili smo sledeće:
pri kliku na dugme menja se vrednost
num, koja se zatim stepenuje
na kvadrat, a pri kliku na naslov
menja se boja naslova.
Imamo veoma malu komponentu, sve radi brzo, uprkos tome što pri kliku na naslov za promenu njegove boje cela komponenta se ponovo iscrtava, shodno tome, ponovo se izvršavaju i proračuni koji su vezani za dugme, i to čak i kada ga nismo dotakli. A sada zamislite da su naši proračuni bili obimni i da se sve ponovo preračunava svaki put.
Hajde da malo opteretimo našu funkciju, sada će "razmišljati" malo duže. Na ovaj način ćemo simulirati dugotrajne proračune:
function square(num) {
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Samo ne radi ništa ...
}
return num * num;
}
Pokušajte sada da klikćete na naslov. Ispostavlja se
da sada, zbog dugog rada funkcije
square (a dugme nismo dotakli)
moramo čitavu večnost da čekamo da bi
naslov promenio boju!
Ovde će nam u pomoć priskočiti huk
useMemo. Za ovo, potrebno je da prvi
parametar prosledimo funkciju koja izračunava
vrednost koju želimo da keširamo,
ova funkcija mora biti čista i ne
prihvatati nikakve parametre. A drugim
parametrom - zavisnosti u uglastim
zagradama, drugim rečima, sve reaktivne
vrednosti koje učestvuju u kodu
funkcije. Tako, u result
sada upisujemo ovakvu konstrukciju:
const result = useMemo(() => square(num), [num]);
Ponovo pokušajte da klikćete na naslov. Sada,
ako ne diramo dugme sa proračunima
i ne menjamo na taj način vrednost stanja
num, onda se ništa ne preračunava,
i React prikazuje keširanu vrednost
u dugmetu, zbog čega naš naslov
brzo menja svoju boju.
Kreirajte komponentu App, postavite
u njoj pasus. Definišite stanje text
sa početnom vrednošću 'react',
neka se vrednost stanja prikazuje
kao tekst pasusa. Neka se pri kliku
na pasus, na kraju teksta dodaje
uzvičnik.
Definišite još jedno stanje num, sa
početnom vrednošću 0. Postavite u
App još jedan pasus. Podesite tako
da pri kliku na njega num
se povećava za 1.
A sada dodajte u App funkciju
triple, koja kao
parametar prihvata num i
vraća njen utrostručen rezultat.
Stavite rezultat poziva funkcije
u promenljivu result. Prikažite
result kao tekst drugog
pasusa. Klikćite redom na pasuse,
primetite kako se sporo dodaju
uzvičnici.
Ispravite situaciju, obavivši sporu
funkciju triple u useMemo.