Hook di ottimizzazione delle prestazioni useMemo in React
Il primo hook per l'ottimizzazione delle
prestazioni che esamineremo
è useMemo.
Questo hook aiuta a memorizzare nella cache i risultati di operazioni che richiedono molte risorse tra i momenti di ridisegno dello schermo e, di conseguenza, può aiutare a evitare calcoli voluminosi non necessari. Questa memorizzazione nella cache è anche chiamata memoizzazione.
Vediamo come funziona. Creiamo
un componente con un pulsante e
un'intestazione h3:
return (
<div>
<h3>Testo</h3>
<button>clicca</button>
</div>
);
Ora facciamo in modo che al click
sull'intestazione, il suo colore cambi da arancione
a verde e viceversa. Per iniziare,
creiamo uno stato isGreen:
const [isGreen, setIsGreen] = useState(false);
Aggiungiamo all'attributo style dell'intestazione
una condizione per cambiare il colore e
aggiungiamo un gestore del click:
<h3 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? 'green' : 'orangered' }}
>Testo</h3>
Supponiamo che ci sia anche un valore che aumenta di uno al click sul nostro pulsante. Creiamo uno stato per esso:
const [num, setNum] = useState(0);
Aggiungiamo la gestione del click sul pulsante:
<button onClick={() => setNum(num + 1)}>
clic
</button>
Supponiamo inoltre che ci sia una funzione
square, che restituirà
il quadrato del valore num. Il risultato
della chiamata della funzione verrà memorizzato in
una variabile result:
const result = square(num);
function square(num) {
return num * num;
}
Visualizziamo result nel testo del pulsante:
<button onClick={() => setNum(num + 1)}>
clic: {result}
</button>
Il risultato è il seguente:
al click sul pulsante cambia il valore
num, che viene poi elevato
al quadrato, e al click sull'intestazione
cambia il colore dell'intestazione.
Il nostro componente è molto piccolo, tutto funziona velocemente, nonostante al click sull'intestazione per cambiarne il colore l'intero componente venga ridisegnato nuovamente, di conseguenza avvengono nuovamente anche i calcoli legati al pulsante, e questo anche se non l'abbiamo toccato. E ora immaginate se i nostri calcoli fossero voluminosi e tutto venisse ricalcolato ogni volta.
Rendiamo la nostra funzione un po' più pesante, ora ci penserà un po' più a lungo. In questo modo simuleremo calcoli lunghi:
function square(num) {
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Non fare nulla ...
}
return num * num;
}
Ora clicca sull'intestazione. Risulta
che a causa del lungo lavoro della funzione
square (e non stiamo toccando il pulsante!)
dobbiamo aspettare un'eternità affinché
l'intestazione cambi colore!
Qui in nostro soccorso arriva l'hook
useMemo. Per fare ciò, dobbiamo passare come primo
parametro una funzione che calcola
il valore che vogliamo memorizzare nella cache;
questa funzione deve essere pura e non
accettare parametri. E come secondo
parametro - le dipendenze tra parentesi quadre,
in altre parole, tutti i valori reattivi
che partecipano nel codice della
funzione. Quindi, in result
scriveremo ora una costruzione così:
const result = useMemo(() => square(num), [num]);
Clicchiamo di nuovo sull'intestazione. Ora,
se non tocchiamo il pulsante con i calcoli
e non cambiamo quindi il valore dello stato
num, allora nulla viene ricalcolato,
e React visualizza il valore memorizzato nella cache
nel pulsante, quindi la nostra intestazione
cambia rapidamente colore.
Crea un componente App, posiziona
al suo interno un paragrafo. Crea uno stato text
con valore iniziale 'react',
lascia che il valore dello stato venga visualizzato
come testo del paragrafo. Fai in modo che al click
sul paragrafo, alla fine del testo venga aggiunto
un punto esclamativo.
Crea un altro stato num, con
valore iniziale 0. Posiziona in
App un altro paragrafo. Fai in modo
che al click su di esso num
aumenti di 1.
E ora aggiungi in App la funzione
triple, che accetta come
parametro num e
restituisce il suo valore triplo.
Metti il risultato della chiamata della funzione
in una variabile result. Visualizza
result come testo del secondo
paragrafo. Clicca in sequenza sui paragrafi,
nota quanto lentamente vengono aggiunti
i punti esclamativi.
Correggi la situazione, avvolgendo la funzione lenta
triple in useMemo.