useCallback og useMemo for bedre ytelse
Memoiser callback-funksjoner med useCallback for å hindre unødvendige nye gjengivelser av underordnede komponenter, og hurtiglagre kostbare beregnede verdier med useMemo.
useCallback og useMemo for bedre ytelse er en gratis leksjon i React Native Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i React Native Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i React Native Academy inneholder totalt 4 leksjoner.
Problemet med nye gjengivelser
Hver gang en komponent gjengis på nytt i React, opprettes alle verdier som er laget inne i funksjonskroppen på nytt. Dette omfatter objekter, tabeller og, viktigst av alt, funksjoner. Hvis en funksjon eller verdi som er opprettet på nytt, sendes som en prop til en underordnet komponent, ser den underordnede komponenten en ny referanse og gjengis på nytt, selv om den logiske verdien ikke er endret.
Hva er useCallback?
useCallback(fn, deps) returnerer en memorert versjon av tilbakekallingsfunksjonen som bare endres hvis én av avhengighetene er endret. Når De pakker inn en tilbakekalling i useCallback, bevares den samme funksjonsreferansen mellom gjengivelser. Dermed unngås unødvendige nye gjengivelser i underordnede komponenter som mottar den som en prop.
import { useCallback } from 'react';
function Parent() {
const [count, setCount] = useState(0);
// handlePress is the SAME function reference between renders
// as long as count does not change
const handlePress = useCallback(() => {
console.log('Pressed, count is:', count);
}, [count]);
return <Child onPress={handlePress} />;
}useCallback med React.memo
useCallback er mest effektiv når den kombineres med React.memo på den underordnede komponenten. Uten React.memo gjengis den underordnede komponenten på nytt uansett, uavhengig av om prop-referansen er lik. Kombinasjonen av React.memo på den underordnede komponenten og useCallback på tilbakekallingen i den overordnede komponenten hindrer nye gjengivelser når verken atferden eller dataene er endret.
const ChildButton = React.memo(({ onPress, label }) => (
<Button title={label} onPress={onPress} />
));
function Parent() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
// ChildButton will NOT re-render when text changes
const handleCount = useCallback(() => setCount(c => c + 1), []);
return (
<>
<TextInput value={text} onChangeText={setText} />
<ChildButton label='Count' onPress={handleCount} />
</>
);
}Hva er useMemo?
useMemo(computeFn, deps) memorerer resultatet av en kostbar beregning. React kaller computeFn ved den første gjengivelsen og mellomlagrer returverdien. Ved senere gjengivelser returneres den mellomlagrede verdien, med mindre en avhengighet er endret. Dermed unngås det at tunge beregninger gjentas ved hver gjengivelse.
import { useMemo } from 'react';
function ProductList({ products, category }) {
// Only recomputes when products or category changes
const filtered = useMemo(
() => products.filter((p) => p.category === category),
[products, category]
);
return <FlatList data={filtered} renderItem={renderItem} />;
}useMemo for stabile objektreferanser
Objekter og tabeller som opprettes direkte i JSX, får nye referanser ved hver gjengivelse. Hvis de sendes til en memorert underordnet komponent, motvirker de memoreringsgevinsten. Pakk dem inn i useMemo for å opprette en stabil referanse som bare endres når de underliggende dataene endres. Dette er spesielt viktig for stil-tabeller og konfigurasjonsobjekter.
function Chart({ data, color }) {
// New object on every render without useMemo
const chartConfig = useMemo(() => ({
backgroundColor: color,
dataPoints: data.map((d) => d.value),
}), [data, color]);
return <ChartComponent config={chartConfig} />;
}Avhengighetstabeller: Slik får De dem riktig
Både useCallback og useMemo krever korrekte avhengighetstabeller. Ta med hver verdi fra komponentens scope som brukes inne i den memorerte funksjonen eller beregningen. Hvis en avhengighet mangler, bruker den memorerte verdien en foreldet closure. Hvis De tar med for mange, utføres beregningen unødvendig på nytt. ESLint-regelen exhaustive-deps hjelper med å håndheve korrekthet.
// Wrong: missing userId dependency — stale closure bug
const fetchUser = useCallback(() => fetch('/user/' + userId), []);
// Correct: userId is listed
const fetchUser = useCallback(() => fetch('/user/' + userId), [userId]);Når useCallback IKKE bør brukes
useCallback har en kostnad: React lagrer funksjonen i minnet og kontrollerer avhengighetstabellen ved hver gjengivelse. For enkle håndterere som ikke sendes til memorerte underordnede komponenter, er kostnaden ved useCallback større enn gevinsten. Bruk den med omtanke – bare når den underordnede komponenten er pakket inn i React.memo og likhet mellom props er viktig for ytelsen.
// Unnecessary: Button re-renders anyway; no child is memoized
const handlePress = useCallback(() => setVisible(true), []);
// Fine without useCallback in this case
const handlePress = () => setVisible(true);useMemo for kostbare transformasjoner
Bruk useMemo når en beregning tar merkbart med tid – for eksempel sortering av store tabeller, tolking av komplekse data eller statistiske beregninger. En tommelfingerregel er at De bør vurdere memorerering hvis beregningen tar mer enn ett millisekund og utføres ved hver gjengivelse. For trivielle operasjoner, som å legge sammen to tall, er kostnaden ved memorerering større enn selve beregningen.
const sortedAndFiltered = useMemo(() => {
return items
.filter((item) => item.status === selectedStatus)
.sort((a, b) => b.createdAt - a.createdAt)
.slice(0, 100);
}, [items, selectedStatus]);useCallback for renderItem i FlatList
Når De pakker renderItem-funksjonen til en FlatList inn i useCallback, hindrer De at det opprettes en ny funksjonsreferanse ved hver gjengivelse av den overordnede komponenten. Ellers ville alle synlige FlatList-rader blitt gjengitt på nytt. Dette er et av de mest effektive ytelsestiltakene i React Native-apper som bruker mange lister.
const renderItem = useCallback(({ item }) => (
<ProductCard
product={item}
onPress={handleSelectProduct}
/>
), [handleSelectProduct]); // handleSelectProduct also memoized
<FlatList
data={products}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>Måle effekten
Før De legger til memorerering overalt, bør De måle den faktiske effekten med React DevTools Profiler. Ta opp en interaksjon, se på flammegrafen for å finne komponenter som gjengis unødvendig på nytt, og legg bare til useCallback eller useMemo der profileringen viser en reell flaskehals. For tidlig optimalisering gjør koden mer kompleks uten en målbar gevinst.
Sammenligning
Husk den viktigste forskjellen: useCallback memorerer en funksjon (hindrer at funksjonsreferansen opprettes på nytt), mens useMemo memorerer en beregnet verdi (hindrer at en kostbar beregning kjøres på nytt). Begge tar imot en avhengighetstabell og beregner bare på nytt når de oppførte avhengighetene endres.
// useCallback — memoize a function
const fn = useCallback(() => doSomething(a, b), [a, b]);
// useMemo — memoize a computed value
const val = useMemo(() => computeExpensive(a, b), [a, b]);
// Relationship: useCallback(fn, deps) === useMemo(() => fn, deps)Hurtigsjekk
Test forståelsen Deres av useCallback og useMemo for ytelse fra denne leksjonen.
Oppsummering av leksjonen
I denne leksjonen lærte De at: useCallback memorerer en funksjonsreferanse for å hindre unødvendige nye gjengivelser av underordnede komponenter, useMemo memorerer en kostbar beregnet verdi for å unngå ny beregning ved hver gjengivelse, og begge fungerer best når de kombineres med React.memo og korrekte avhengighetstabeller. Deretter skal vi se på hvordan De kan skrive egendefinerte hooker for å dele tilstandslogikk mellom komponenter.
Lær deg JavaScript med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 30
- Leksjoner
- 120
Ofte stilte spørsmål
Er leksjonen «useCallback og useMemo for bedre ytelse» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien React Native Academy, inkludert «useCallback og useMemo for bedre ytelse», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i React Native Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «useCallback og useMemo for bedre ytelse»?
Memoiser callback-funksjoner med useCallback for å hindre unødvendige nye gjengivelser av underordnede komponenter, og hurtiglagre kostbare beregnede verdier med useMemo. Du øver på React Native Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med React Native Academy?
Ingen tidligere erfaring er nødvendig. React Native Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.
Hvor lang tid tar leksjonen «useCallback og useMemo for bedre ytelse»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne React Native Academy-leksjonen?
Ja. Alle React Native Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- useRef for DOM-noder og mutable verdier
- useReducer for kompleks tilstandslogikk
- useCallback og useMemo for bedre ytelse
- Skrive egendefinerte hooker