Hukken useCallback for ytelsesoptimalisering i React
I denne leksjonen skal vi se på følgende
hukk for ytelsesoptimalisering
useCallback.
Hukken useCallback ligner på API-et useMemo,
forskjellen ligger i at den første
mellomlagrer en verdi mellom gjengivelsene,
mens den andre - en tilbakekalling.
Dette lar oss unngå å kjøre ressurskrevende
funksjoner på nytt når det ikke er nødvendig og kan
brukes ved
overføring av en funksjon
til underkomponenter.
La oss undersøke nærmere med et eksempel.
Først oppretter vi en komponent App
og lager en tilstand num i den:
const [num, setNum] = useState(0);
La oss ha en knapp som ved klikk
øker num
med 1, og et avsnitt der vi
skal vise verdien av num:
return (
<div>
<button onClick={() => setNum(num + 1)}>klikk</button>
<p>klikk: {num}</p>
</div>
);
La oss nå anta at vi i
App også viser en liste
med elementer som vi vil utvide
ved å trykke på en annen knapp. For å lagre
elementene i denne listen oppretter vi
en tilstand items:
const [items, setItems] = useState([]);
Og deretter skriver vi funksjonen addItem
for å legge dem til:
function addItem() {
setItems([...items, 'nytt element']);
}
La oss nå skrive koden for visning
av listeelementene og flytte den til en underkomponent
Items, som som props
vil motta en matrise med elementer
og en funksjon for å legge dem til. La oss ikke glemme
å legge til en utskrift til konsollen for å se
når Items vår
blir gjengitt på nytt:
function Items({ items, addItem }) {
const result = items.map((item, index) => {
return <p key={index}>{item}</p>;
});
console.log('Items gjengis');
return (
<div>
<h3>Våre elementer</h3>
{result}
<button onClick={addItem}>legg til element</button>
</div>
);
}
export default Items;
La oss plassere Items på slutten av komponenten
App og sende den matrisen
items og funksjonen for å legge til
elementer addItem:
return (
<>
<div>
<button onClick={() => setNum(num + 1)}>klikk</button>
<p>klikk: {num}</p>
<br />
</div>
<Items items={items} addItem={addItem} />
</>
);
La oss nå trykke på knappene
og forsikre oss om at num øker og
nye elementer legges til i listen.
Og ved å åpne konsollen vil vi se at
listen vår gjengis på nytt hver
gang, selv om vi klikker på knappen
som øker num.
Hvis vi har en liten liste, er alt
greit, men hvis det er forventet at den
skal være omfangsrik og at det er mye annet der?
Ikke noe problem - sier du kanskje, for i forrige
leksjon så vi på API-et memo,
for nettopp å unngå unødvendige gjengivelser
av en komponent.
Så la oss pakke komponenten vår
Items inn i memo, så ordner det seg.
Dette kan forresten gjøres direkte
ved eksport av Items:
export default memo(Items);
La oss ikke glemme å importere memo:
import { memo } from 'react';
La oss nå åpne konsollen og trykke på
knappene. Alle anstrengelser til ingen nytte! Vi
memoiserte komponenten, men ved trykk
på knappen 'klikk' blir komponenten
Items likevel
gjengitt på nytt hver gang.
Grunnen er at når foreldrekomponenten
gjengis på nytt, blir funksjonene dens
gjenopprettet på nytt - dette gjelder også vår
funksjon addItem, som vi sender til
Items.
Nettopp i dette øyeblikket vil hukken
useCallback hjelpe oss. La oss bruke
den. Først importerer vi den til
App:
import { useCallback } from 'react';
Deretter endrer vi den enkle deklarasjonen av funksjonen
addItem til et
Function Expression, angir som
første parameter for useCallback
vår funksjon som en tilbakekalling. Som andre
parameter i klammeparentesene angir vi
avhengigheter - alle reaktive variabler
som deltar i funksjonen, i vårt tilfelle
er dette matrisen items:
const addItem = useCallback(() => {
setItems(() => [...items, 'Nytt element']);
}, [items]);
Ferdig! På denne måten har vi mellomlagret
funksjonen. Vi trykker på knappene igjen og
ser at nå, ved trykk på knappen
'klikk', blir ikke underkomponenten vår
gjengitt på nytt.
Opprett en komponent App, plasser
i den et avsnitt med tekst. Opprett
en tilstand med startverdi 'tekst'
og vis den i avsnittet. La det ved klikk
på avsnittet legges til et utropstegn
på slutten av teksten.
Opprett en underkomponent Products,
der du har en knapp for å legge til
et nytt produkt. Plasser den i App.
I foreldrekomponenten oppretter du en tilstand
med en matrise av produkter og en funksjon for å legge til
et nytt produkt. Send dem som
props til underkomponenten, vis i den
den overførte matrisen som en liste ul.
I Products skriv ut teksten
'products gjengis' til konsollen.
Pakk Products inn i memo.
Trykk på avsnittet og knappen. Forsikre deg om
at ved klikk på avsnittet blir underkomponenten
likevel gjengitt på nytt.
Mellomlagre funksjonen for å legge til
produkter ved å pakke den inn i hukken useCallback.
Trykk på avsnittet og knappen. Forsikre deg om
at ved klikk på avsnittet blir underkomponenten
ikke lenger gjengitt på nytt.