Prestatie-optimalisatie hook useMemo in React
De eerste hook voor prestatie-optimalisatie
die we gaan bekijken
is useMemo.
Deze hook helpt bij het cachen van resultaten van resource-intensieve bewerkingen tussen momenten van schermhertekening en kan zo helpen onnodige omvangrijke berekeningen te vermijden. Dit soort cachen wordt ook wel memoïsatie genoemd.
Laten we kijken hoe dit werkt. Laten we
een component maken met een knop en
een h3 kop:
return (
<div>
<h3>Text</h3>
<button>click</button>
</div>
);
Laten we nu ervoor zorgen dat bij een klik
op de kop de kleur verandert van oranje
naar groen en vice versa. Laten we om te beginnen
een state isGreen aanmaken:
const [isGreen, setIsGreen] = useState(false);
Laten we aan het style attribuut van de kop
een voorwaarde toevoegen voor het wijzigen van de kleur en
een click handler toevoegen:
<h3 onClick={() => setIsGreen(!isGreen)}
style={{ color: isGreen ? 'green' : 'orangered' }}
>Text</h3>
Laten we ook een waarde hebben die met één wordt verhoogd bij een klik op onze knop. Laten we hiervoor een state aanmaken:
const [num, setNum] = useState(0);
Laten we de click handler voor de knop toevoegen:
<button onClick={() => setNum(num + 1)}>
clicks
</button>
Laten we ook een functie square hebben,
die het kwadraat van de waarde num teruggeeft.
Het resultaat
van de functieaanroep schrijven we in een
variabele result:
const result = square(num);
function square(num) {
return num * num;
}
Laten we result weergeven in de knoptekst:
<button onClick={() => setNum(num + 1)}>
clicks: {result}
</button>
Het resultaat is als volgt:
bij een klik op de knop verandert de waarde
num, die vervolgens wordt
gekwadrateerd, en bij een klik op de kop
verandert de kleur van de kop.
We hebben een zeer kleine component, alles werkt snel, ondanks het feit dat bij een klik op de kop om de kleur te veranderen de hele component opnieuw wordt gerenderd, en dus ook de berekeningen opnieuw plaatsvinden die aan de knop zijn gekoppeld, zelfs als we hem niet hebben aangeraakt. En stel je nu voor dat onze berekeningen omvangrijk waren en alles elke keer opnieuw zou worden berekend.
Laten we onze functie een beetje zwaarder maken, nu zal hij iets langer nadenken. Op deze manier simuleren we langdurige berekeningen:
function square(num) {
let startTime = performance.now();
while (performance.now() - startTime < 500) {
// Gewoon niets doen ...
}
return num * num;
}
Klik nu maar op de kop. Het blijkt
dat we nu, vanwege het langzame werken van de functie
square (en we raken de knop niet aan)
een eeuwigheid moeten wachten voordat de
kleur van de kop verandert!
Hier komt de hook
useMemo ons te hulp. Hiervoor moeten we als eerste
parameter een functie doorgeven die de
waarde berekent die we willen cachen.
Deze functie moet puur zijn en
geen parameters accepteren. En als tweede
parameter - de afhankelijkheden tussen vierkante
haken, met andere woorden, alle reactieve
waarden die betrokken zijn bij de code
van de functie. Dus, in result
schrijven we nu zo'n constructie:
const result = useMemo(() => square(num), [num]);
Laten we weer op de kop klikken. Nu,
als we de knop met berekeningen niet aanraken
en dus de state waarde
num niet veranderen, dan wordt er
niets opnieuw berekend,
en React toont de gecachte waarde
in de knop, daarom verandert onze kop
snel van kleur.
Maak een component App aan, plaats
daarin een alinea. Maak een state text aan
met beginwaarde 'react',
laat de state waarde worden weergegeven
als de tekst van de alinea. Laat bij een klik
op de alinea, aan het einde van de tekst een
uitroepteken worden toegevoegd.
Maak nog een state num aan, met
beginwaarde 0. Plaats in
App nog een alinea. Zorg ervoor
dat bij een klik erop num
met 1 wordt verhoogd.
En voeg nu in App de functie
triple toe, die als
parameter num accepteert en
zijn drievoudige waarde teruggeeft.
Plaats het resultaat van de functieaanroep
in de variabele result. Toon
result als de tekst van de tweede
alinea. Klik om de beurt op de alinea's,
merk op hoe langzaam de
uitroeptekens worden toegevoegd.
Verbeter de situatie door de langzame
functie triple in useMemo te wikkelen.