useMemo: vad är det, cachning av beräkningar och React Native

Författare: IT Sectr Publicerad: 2026-07-05 Lästid: 10 min

Hooken useMemo i React Native memoiserar resultatet av beräkningar mellan komponentens renderingar och förhindrar upprepad exekvering av dyra operationer. Till skillnad från useCallback som memoiserar en funktion, sparar useMemo det returnerade värdet och beräknar om det endast när de angivna beroendena ändras. Enligt React Docs, 2024 är memoisering särskilt effektiv för beräkningar med stora arrayer och komplexa datatransformationer. I React Native skapar varje extra omrendering ytterligare belastning på bryggförbindelsen mellan JavaScript och inbyggda trådar, så korrekt användning av useMemo påverkar direkt smidigheten i animationer och gränssnittets svarstid.

Huvudpunkter

  • useMemo — React hook för memoisering av värden, som cachar funktionens resultat mellan renderingar
  • Hooken tar emot två argument: en beräkningsfunktion och en beroendematris
  • Värdet beräknas om endast när minst ett beroende ändras
  • I React Native är useMemo avgörande för att optimera prestandan hos listor och animationer
  • Missbruk av useMemo kan försämra prestandan på grund av kostnaden för att jämföra beroenden

Vad är useMemo i React Native

useMemo — är en hook från Reacts standardbibliotek, tillgänglig i React Native utan extra paket. Den memoiserar värdet som returneras av den skickade funktionen och återanvänder detta värde i efterföljande renderingar tills de beroenden som anges i matrisen ändras.

Hookens namn kommer från engelskans memoization — en optimeringsteknik där resultatet av en dyr funktion lagras i cache. Vid upprepad anrop med samma argument returneras det lagrade värdet istället för omberäkning.

I React Native-sammanhang är memoisering särskilt viktig på grund av arkitekturen. Varje omrendering av en komponent skickar data genom bryggan JavaScript — Native, vilket tar tid. Om komponenten innehåller dyra beräkningar (filtrering av lista, sortering, formatering) kommer varje omrendering att upprepa dem, blockera JS-tråden och orsaka tappade bildrutor.

Enligt React Native Performance Docs, 2024 är flaskhalsen oftast inte rendering av inbyggda komponenter, utan exekvering av JavaScript-logik mellan renderingar. useMemo löser exakt detta problem.

Hur fungerar memoisering av värden

useMemo tar emot en funktion och en beroendematris och returnerar ett memoiserat värde. React lagrar det föregående värdet och beroendematrisen. Vid varje rendering jämför React de aktuella beroendena med de föregående med hjälp av Object.is. Om minst ett beroende har ändrats exekveras funktionen igen och resultatet sparas.

Syntax och överföring av argument

Signaturen för useMemo är helt identisk på webben och i React Native. Det första argumentet — en funktion utan parametrar som returnerar värdet som ska memoiseras. Det andra — beroendematrisen, vid vars ändring värdet kommer att beräknas om.

js
import React, { useMemo } from 'react';

const sortedList = useMemo(() => {
    return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);

I detta exempel beräknas sortedList om endast när referensen till items-matrisen ändras. Om matrisen har ändrats till innehållet men referensen förblir densamma (mutation) kommer useMemo inte att se ändringarna — detta är en viktig begränsning.

Jämförelse av beroenden via Object.is

React använder Object.is-algoritmen för att jämföra beroenden, vilken fungerar liknande strikt likhet === men hanterar NaN korrekt (+0 och -0 anses vara olika). Detta innebär att för primitiva typer (strängar, tal, booleaner) fungerar jämförelsen efter värde, och för objekt och matriser — efter referens.

js
// Object.is({'a': 1}, {'a': 1}) -> false (olika referenser)
// Object.is(42, 42) -> true (primitiv efter värde)
// Object.is(NaN, NaN) -> true (korrekt hantering av NaN)

Att förstå denna mekanism är avgörande: om du skickar ett nytt objekt i beroendena vid varje rendering kommer memoiseringen att vara värdelös eftersom beroendena kommer att anses vara ändrade varje gång.

När ska man använda useMemo

useMemo är motiverat i tre scenarier: dyra beräkningar, överföring av stabila props till barnkomponenter och bevarande av referensiell identitet hos objekt. I React Native förekommer alla tre scenarier regelbundet på grund av mobilapplikationernas arkitektur.

Dyra beräkningar

Om komponenten utför bearbetning av stora datamatriser (filtrering, sortering, gruppering) eller resurskrävande matematiska operationer, förhindrar useMemo upprepning av dessa beräkningar vid varje omrendering. I mobila applikationer är ett typiskt exempel formatering av data från API före visning i en lista.

Stabila props för barnkomponenter

När en barnkomponent är inslagen i React.memo omrenderas den endast när props ändras. Om props-objektet skapas inuti föräldern utan useMemo, kommer varje rendering av föräldern att skapa en ny referens och barnkomponenten kommer att renderas om, vilket ogiltigförklarar fördelen med React.memo.

Memoisering av stilberäkningar

I React Native är stilar ofta beroende av props — till exempel beräknas en elements bredd baserat på skärmstorleken. useMemo gör det möjligt att beräkna sådana dynamiska stilar endast när indataparametrarna ändras.

När är useMemo värdelöst

useMemo är inte ett universellt optimeringsverktyg. I vissa scenarier ger det ingen fördel och kan till och med försämra prestandan på grund av omkostnader för lagring och jämförelse av beroenden. I React Native, där varje byte minne räknas, är blint användande av useMemo utan att mäta effekten ett anti-mönster.

Hooken ger ingen fördel i tre huvudfall. För det första, om beräkningen är trivial (enkel addition, strängkonkatenering) överstiger kostnaderna för useMemo värdet av själva beräkningen. För det andra, om beroendena ändras vid varje rendering — funktionen kommer ändå att exekveras och memoiseringen tillför bara extra arbete. För det tredje, om komponenten renderas sällan är omkostnaden för cache-lagring inte motiverad.

Enligt Kent C. Dodds, 2023 måste du innan du lägger till useMemo mäta problemet med React DevTools Profiler eller den inbyggda Performance Monitor i React Native. Om komponentens omrendering tar mindre än 1 ms är memoisering inte nödvändig.

  • Triviala beräkningar — addition, konkatenering, enkla ternära operationer
  • Sällsynta omrenderingar — statiska skärmar som renderas en gång
  • Ändrade beroenden — om beroendena är nya vid varje rendering är memoisering värdelös
  • Primitiva värden — tal och strängar kräver inte memoisering, de är ändå billiga

useMemo och useCallback: jämförelse

useMemo och useCallback — två memoiseringshooks från React som ofta förväxlas. Skillnaden ligger i vad de sparar: useMemo returnerar resultatet av funktionsexekveringen (vilket värde som helst), medan useCallback returnerar själva funktionen. Båda tar emot en beroendematris, men syntaxen skiljer sig.

EgenskapuseMemouseCallback
ReturnerarResultat av funktionsexekveringReferens till funktionen
Första argumentetFunktion som returnerar ett värdeFunktion som ska memoiseras
Typisk användningCachning av beräkningarStabila callbacks för barnkomponenter
EkvivalensuseMemo(() => fn, deps)useCallback(fn, deps) === useMemo(() => fn, deps)

I praktiken är useCallback syntaktiskt socker över useMemo för fallet när en funktion behöver memoiseras. I React Native används båda hooks lika ofta: useMemo — för data (formaterad text, beräknade stilar), useCallback — för händelsehanterare (onPress, onChangeText).

Praktiska exempel med useMemo

Låt oss titta på två verkliga scenarier för användning av useMemo i React Native-applikationer. Det första — filtrering av en kontaktlista baserat på sökfråga, det andra — beräkning av dynamiska stilar baserat på skärmstorlek.

Exempel 1: sökning och filtrering av lista

I detta exempel förhindrar useMemo omfiltrering av den stora kontaktlistan vid varje rendering, om varken sökfrågan eller källdata har ändrats.

js
const ContactList = ({ contacts, searchQuery }) => {
    const filteredContacts = useMemo(() => {
        if (!searchQuery.trim()) return contacts;
        const query = searchQuery.toLowerCase();
        return contacts.filter((c) =>
            c.name.toLowerCase().includes(query) ||
            c.phone.includes(query)
        );
    }, [contacts, searchQuery]);

    return (
        <FlatList
            data={filteredContacts}
            renderItem={renderContact}
            keyExtractor={(item) => item.id}
        />
    );
};

Utan useMemo skulle filtreringen utföras vid varje rendering, inklusive de som orsakats av animationer eller tillståndsändringar i andra delar av komponenten. Med useMemo utlöses filtreringen endast när contacts eller searchQuery ändras.

Exempel 2: beräkning av dynamiska stilar

I React Native är stilar ofta beroende av skärmstorleken eller komponentens props. useMemo gör det möjligt att beräkna ett sådant stilobjekt en gång och återanvända det tills beroendena ändras.

js
const Card = ({ title, isSelected }) => {
    const cardStyle = useMemo(() => ({
        backgroundColor: isSelected ? '#e3f2fd' : '#ffffff',
        borderWidth: isSelected ? 2 : 1,
        padding: 16,
    }), [isSelected]);

    return (
        <View style={cardStyle}>
            <Text>{title}</Text>
        </View>
    );
};

Detta tillvägagångssätt garanterar att cardStyle-objektet förblir stabilt (samma referens) tills isSelected ändras. Om Card är inslagen i React.memo förhindrar detta mönster onödiga omrenderingar av barn-element.

Vanliga frågor

Vad returnerar useMemo?

useMemo returnerar det memoiserade värdet — resultatet av exekveringen av funktionen som skickats som första argument. Vid efterföljande renderingar returnerar React det lagrade värdet om beroendena inte har ändrats.

Vad är skillnaden mellan useMemo och useCallback?

useMemo returnerar resultatet av funktionsexekveringen (vilket värde som helst: tal, objekt, JSX), medan useCallback returnerar själva funktionen. Dessutom är useCallback(fn, deps) ekvivalent med useMemo(() => fn, deps).

När behövs inte useMemo?

useMemo är värdelöst vid triviala beräkningar (addition, konkatenering), sällsynta omrenderingar, beroenden som ändras vid varje rendering och för primitiva typer. Mät alltid prestandan innan du lägger till useMemo.

Kan useMemo försämra prestandan?

Ja, om det används i onödan. React lagrar tidigare värden i minnet och utför jämförelse av beroenden vid varje rendering. För enkla beräkningar överstiger omkostnaden för dessa operationer fördelen med memoisering.

Hur felsöker man useMemos funktion?

Använd React DevTools Profiler för att mäta renderingstiden för komponenter. I React Native finns även Performance Monitor tillgänglig via utvecklarmenyn. Om omrenderingen tar mindre än 1 ms — behövs inte useMemo.

Sammanfattning

  • useMemo — React hook för memoisering av värden, som cachar funktionens resultat mellan renderingar
  • Hooken tar emot en beräkningsfunktion och en beroendematris, och beräknar om värdet endast när de ändras
  • I React Native är useMemo särskilt viktigt för att optimera listor, animationer och komplexa beräkningar
  • Nyckelscenarier: dyra beräkningar, stabila props för React.memo, dynamiska stilar
  • useMemo skiljer sig från useCallback: det första returnerar ett värde, det andra — en funktion
  • Missbruk av useMemo försämrar prestandan på grund av omkostnaden för lagring och jämförelse av beroenden
  • Innan du lägger till useMemo, mät alltid problemet med React DevTools Profiler eller Performance Monitor i React Native

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också