useMemo: ce este, memorarea în cache a calculelor și React Native

Autor: IT Sectr Publicat: 2026-07-05 Timp de citire: 10 min

Hook-ul useMemo din React Native memoizează rezultatul calculelor între randările componentei, prevenind executarea repetată a operațiilor costisitoare. Spre deosebire de useCallback, care memoizează funcția, useMemo păstrează valoarea returnată și o recalculează doar la modificarea dependințelor specificate. Conform React Docs, 2024, memoizarea este deosebit de eficientă pentru calcule cu tablouri mari și transformări complexe de date. În React Native, fiecare re-renderizare suplimentară creează o sarcină suplimentară pe conexiunea punte dintre firele JavaScript și native, astfel că utilizarea corectă a useMemo influențează direct fluența animațiilor și viteza de răspuns a interfeței.

Puncte cheie

  • useMemo — hook-ul React pentru memoizarea valorilor, care memorează rezultatul funcției între randări
  • Hook-ul primește două argumente: o funcție de calcul și un tablou de dependințe
  • Valoarea se recalculează doar când cel puțin o dependință se modifică
  • În React Native, useMemo este esențial pentru optimizarea performanței listelor și animațiilor
  • Abuzul de useMemo poate înrăutăți performanța din cauza costurilor de comparare a dependințelor

Ce este useMemo în React Native

useMemo — este un hook din biblioteca standard React, disponibil în React Native fără pachete suplimentare. Acesta memoizează valoarea returnată de funcția transmisă și reutilizează această valoare în randările ulterioare până când dependințele specificate în tablou se modifică.

Numele hook-ului provine din englezescul memoization — o tehnică de optimizare prin care rezultatul unei funcții costisitoare este stocat în cache. La apelul repetat cu aceleași argumente, se returnează valoarea salvată în locul recalculării.

În contextul React Native, memoizarea este deosebit de importantă datorită arhitecturii specifice. Fiecare re-renderizare a componentei trimite date prin puntea JavaScript — Nativo, ceea ce consumă timp. Dacă componenta conține calcule costisitoare (filtrarea listei, sortare, formatare), fiecare re-renderizare le va repeta, blocând firul JS și cauzând căderi de cadre.

Conform React Native Performance Docs, 2024, blocajul cel mai frecvent nu este randarea componentelor native, ci execuția logicii JavaScript între randări. useMemo rezolvă exact această problemă.

Cum funcționează memoizarea valorilor

useMemo primește o funcție și un tablou de dependințe, returnând o valoare memoizată. React stochează valoarea anterioară și tabloul de dependințe. La fiecare randare, React compară dependințele curente cu cele anterioare folosind Object.is. Dacă cel puțin o dependință s-a modificat, funcția se execută din nou, iar rezultatul este salvat.

Sintaxa și transmiterea argumentelor

Semnătura useMemo este complet identică în web și în React Native. Primul argument — o funcție fără parametri, care returnează valoarea de memoizat. Al doilea — tabloul de dependințe, la modificarea cărora valoarea va fi recalculată.

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

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

În acest exemplu, sortedList se recalculează doar când se modifică referința tabloului items. Dacă tabloul s-a modificat ca conținut, dar referința a rămas aceeași (mutație), useMemo nu va observa schimbările — aceasta este o limitare importantă.

Compararea dependințelor prin Object.is

React folosește pentru compararea dependințelor algoritmul Object.is, care funcționează similar cu egalitatea strictă ===, dar gestionează corect NaN (+0 și -0 sunt considerate diferite). Aceasta înseamnă că pentru tipurile primitive (șiruri, numere, booleeni) compararea funcționează după valoare, iar pentru obiecte și tablouri — după referință.

js
// Object.is({'a': 1}, {'a': 1}) -> false (referințe diferite)
// Object.is(42, 42) -> true (primitiv după valoare)
// Object.is(NaN, NaN) -> true (gestionarea corectă a NaN)

Înțelegerea acestui mecanism este critică: dacă transmiți în dependințe un obiect nou la fiecare randare, memoizarea va fi inutilă, deoarece dependințele vor fi considerate modificate de fiecare dată.

Când să folosești useMemo

useMemo este justificat în trei scenarii: calcule costisitoare, transmiterea de props-uri stabile către componentele copil și păstrarea identității referențiale a obiectelor. În React Native, toate trei scenariile apar regulat datorită specificului arhitecturii aplicațiilor mobile.

Calcule costisitoare

Dacă componenta execută procesarea tablourilor mari de date (filtrare, sortare, grupare) sau operații matematice consumatoare de resurse, useMemo previne repetarea acestor calcule la fiecare re-renderizare. În aplicațiile mobile, un exemplu tipic este formatarea datelor din API înainte de afișarea în listă.

Props-uri stabile pentru componentele copil

Când componenta copil este înfășurată în React.memo, aceasta se re-renderizează doar la modificarea props-urilor. Dacă obiectul props este creat în interiorul părintelui fără useMemo, la fiecare randare a părintelui se va crea o nouă referință, iar componenta copil se va randai din nou, anulând beneficiul React.memo.

Memoizarea calculelor de stiluri

În React Native, stilurile depind adesea de props-uri — de exemplu, lățimea unui element se calculează pe baza dimensiunii ecranului. useMemo permite calcularea acestor stiluri dinamice doar la modificarea parametrilor de intrare.

Când useMemo este inutil

useMemo nu este un mijloc universal de optimizare. În unele scenarii, nu aduce beneficii și poate chiar înrăutăți performanța din cauza cheltuielilor suplimentare de stocare și comparare a dependințelor. În React Native, unde fiecare octet de memorie contează, utilizarea oarbă a useMemo fără măsurarea efectului este un anti-pattern.

Hook-ul nu aduce beneficii în trei cazuri principale. În primul rând, dacă calculul este trivial (adunare simplă, concatenare de șiruri), costurile useMemo depășesc valoarea calculului în sine. În al doilea rând, dacă dependințele se schimbă la fiecare randare — funcția se va executa oricum, iar memoizarea va adăuga doar muncă suplimentară. În al treilea rând, dacă componenta se randaează rar, cheltuiala de stocare a cache-ului nu este justificată.

Conform Kent C. Dodds, 2023, înainte de a adăuga useMemo, trebuie să măsori problema cu ajutorul React DevTools Profiler sau al Performance Monitor încorporat în React Native. Dacă re-renderizarea componentei durează mai puțin de 1 ms, memoizarea nu este necesară.

  • Calcule trivia — adunare, concatenare, operații ternare simple
  • Re-renderizări rare — ecrane statice care se randaează o singură dată
  • Dependințe variabile — dacă dependințele sunt noi la fiecare randare, memoizarea este inutilă
  • Valori primitive — numerele și șirurile nu necesită memoizare, ele sunt oricum ieftine

useMemo și useCallback: comparație

useMemo și useCallback — două hook-uri de memoizare din React care sunt adesea confundate. Diferența constă în ceea ce păstrează: useMemo returnează rezultatul executării funcției (orice valoare), iar useCallback returnează funcția însăși. Ambele primesc un tablou de dependințe, dar sintaxa diferă.

CaracteristicăuseMemouseCallback
ReturneazăRezultatul executării funcțieiReferința la funcție
Primul argumentFuncția care returnează valoareaFuncția de memoizat
Utilizare tipicăMemorarea în cache a calculelorCallback-uri stabile pentru componentele copil
EchivalențăuseMemo(() => fn, deps)useCallback(fn, deps) === useMemo(() => fn, deps)

În practică, useCallback este zahăr sintactic peste useMemo pentru cazul când trebuie memoizată o funcție. În React Native, ambele hook-uri se folosesc la fel de des: useMemo — pentru date (text formatat, stiluri calculate), useCallback — pentru handler-e de evenimente (onPress, onChangeText).

Exemple practice cu useMemo

Să analizăm două scenarii reale de utilizare a useMemo în aplicațiile React Native. Primul — filtrarea listei de contacte după interogarea de căutare, al doilea — calcularea stilurilor dinamice pe baza dimensiunii ecranului.

Exemplul 1: căutarea și filtrarea listei

În acest exemplu, useMemo previne re-filtrarea listei mari de contacte la fiecare randare, dacă nu s-au modificat nici interogarea de căutare, nici datele sursă.

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}
        />
    );
};

Fără useMemo, filtrarea s-ar executa la fiecare randare, inclusiv cele cauzate de animații sau modificări de stare ale altor părți ale componentei. Cu useMemo, filtrarea se declanșează doar la modificarea contacts sau searchQuery.

Exemplul 2: calcularea stilurilor dinamice

În React Native, stilurile depind adesea de dimensiunile ecranului sau de props-urile componentei. useMemo permite calcularea unui astfel de obiect de stiluri o singură dată și reutilizarea lui până când dependințele se modifică.

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>
    );
};

Această abordare garantează că obiectul cardStyle rămâne stabil (aceeași referință) până când isSelected se modifică. Dacă Card este înfășurat în React.memo, acest model previne re-renderizările inutile ale elementelor copil.

Întrebări frecvente

Ce returnează useMemo?

useMemo returnează valoarea memoizată — rezultatul executării funcției transmise ca prim argument. La randările ulterioare, React returnează valoarea salvată dacă dependințele nu s-au modificat.

Cu ce se deosebește useMemo de useCallback?

useMemo returnează rezultatul executării funcției (orice valoare: număr, obiect, JSX), iar useCallback returnează funcția însăși. În plus, useCallback(fn, deps) este echivalent cu useMemo(() => fn, deps).

Când nu este necesar useMemo?

useMemo este inutil la calcule trivia (adunare, concatenare), re-renderizări rare, dependințe care se schimbă la fiecare randare și pentru tipurile primitive. Măsoară întotdeauna performanța înainte de a adăuga useMemo.

Poate useMemo să înrăutățească performanța?

Da, dacă este folosit fără necesitate. React stochează valorile anterioare în memorie și execută compararea dependințelor la fiecare randare. Pentru calcule simple, cheltuiala acestor operații depășește beneficiul memoizării.

Cum se depanează funcționarea useMemo?

Folosește React DevTools Profiler pentru măsurarea timpului de randare a componentelor. În React Native, este disponibil și Performance Monitor prin meniul de dezvoltator. Dacă re-renderizarea durează mai puțin de 1 ms — useMemo nu este necesar.

Concluzii

  • useMemo — hook-ul React pentru memoizarea valorilor, care memorează rezultatul funcției între randări
  • Hook-ul primește o funcție de calcul și un tablou de dependințe, recalculând valoarea doar la modificarea acestora
  • În React Native, useMemo este deosebit de important pentru optimizarea listelor, animațiilor și calculelor complexe
  • Scenarii cheie: calcule costisitoare, props-uri stabile pentru React.memo, stiluri dinamice
  • useMemo se deosebește de useCallback: primul returnează valoarea, al doilea — funcția
  • Abuzul de useMemo înrăutățește performanța din cauza cheltuielii de stocare și comparare a dependințelor
  • Înainte de a adăuga useMemo, măsoară întotdeauna problema prin React DevTools Profiler sau Performance Monitor în React Native

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și