useMemo: шта је, кеширање израчунавања и React Native

Аутор: IT Sectr Објављено: 2026-07-05 Време читања: 10 мин

Хук useMemo у React Native мемоизира резултат прорачуна између рендеровања компоненте, спречавајући поновно извршавање скупих операција. За разлику од useCallback-а, који мемоизира функцију, useMemo чува повратну вредност и поново је израчунава само када се промене наведене зависности. Према React Docs, 2024, мемоизација је посебно ефикасна за прорачуне са великим низовима и сложене трансформације података. У React Native свако додатно поновно рендеровање ствара додатно оптерећење на мостној вези између JavaScript и матичних нити, тако да правилна употреба useMemo-а директно утиче на глаткоћу анимација и брзину одзива интерфејса.

Главне тачке

  • useMemo — React хук за мемоизацију вредности, који кешира резултат функције између рендеровања
  • Хук прихвата два аргумента: функцију за израчунавање и низ зависности
  • Вредност се поново израчунава само када се промени бар једна зависност
  • У React Native useMemo је кључан за оптимизацију перформанси листи и анимација
  • Злоупотреба useMemo-а може погоршати перформансе због трошкова поређења зависности

Шта је useMemo у React Native

useMemo — је хук из стандардне React библиотеке, доступан у React Native без додатних пакета. Он мемоизира вредност коју враћа прослеђена функција и поново користи ту вредност у наредним рендеровањима све док се не промене зависности наведене у низу.

Име хука потиче од енглеског memoization — технике оптимизације при којој се резултат скупе функције чува у кешу. При поновном позиву са истим аргументима враћа се сачувана вредност уместо поновног израчунавања.

У контексту React Native, мемоизација је посебно важна због архитектуре. Свако поновно рендеровање компоненте шаље податке кроз мост JavaScript — Матични, што захтева време. Ако компонента садржи скупе прорачуне (филтрирање листе, сортирање, форматирање), свако поновно рендеровање ће их понављати, блокирајући JS нит и изазивајући пад фрејмова.

Према React Native Performance Docs, 2024, уско грло најчешће није рендеровање матичних компоненти, већ извршавање JavaScript логике између рендеровања. useMemo решава управо овај проблем.

Како функционише мемоизација вредности

useMemo прихвата функцију и низ зависности, враћајући мемоизовану вредност. React чува претходну вредност и низ зависности. При сваком рендеровању React пореди тренутне зависности са претходним користећи Object.is. Ако се променила бар једна зависност, функција се поново извршава и резултат се чува.

Синтакса и прослеђивање аргумената

Потпис useMemo-а је потпуно идентичан на вебу и у React Native. Први аргумент — функција без параметара, која враћа вредност за мемоизацију. Други — низ зависности, при чијој промени ће вредност бити поново израчуната.

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

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

У овом примеру sortedList се поново израчунава само када се промени референца низа items. Ако се низ променио по садржају, али је референца остала иста (мутација), useMemo неће видети промене — ово је важно ограничење.

Поређење зависности путем Object.is

React користи за поређење зависности алгоритам Object.is, који ради слично строгој једнакости ===, али исправно рукује NaN (+0 и -0 се сматрају различитим). То значи да за примитивне типове (стрингови, бројеви, булови) поређење ради по вредности, а за објекте и низове — по референци.

js
// Object.is({'a': 1}, {'a': 1}) -> false (различите референце)
// Object.is(42, 42) -> true (примитив по вредности)
// Object.is(NaN, NaN) -> true (исправно руковање NaN-ом)

Разумевање овог механизма је кључно: ако прослеђујете у зависности нови објекат при сваком рендеровању, мемоизација ће бити бескорисна, јер ће се зависности сматрати промењеним сваки пут.

Када користити useMemo

useMemo је оправдан у три сценарија: скупи прорачуни, прослеђивање стабилних пропсова компонентама деце и очување референцијалног идентитета објеката. У React Native се сва три сценарија редовно јављају због специфичности архитектуре мобилних апликација.

Скупи прорачуни

Ако компонента врши обраду великих низова података (филтрирање, сортирање, груписање) или ресурсно захтевне математичке операције, useMemo спречава понављање ових прорачуна при сваком поновном рендеровању. У мобилним апликацијама типичан пример је форматирање података из API-ја пре приказа у листи.

Стабилни пропсови за компоненте деце

Када је компонента дете омотана у React.memo, она се поново рендерује само при промени пропсова. Ако се пропс објекат креира унутар родитеља без useMemo-а, при сваком рендеровању родитеља ће се креирати нова референца, а компонента дете ће се рендеровати изнова, поништавајући предност React.memo-а.

Мемоизација прорачуна стилова

У React Native стилови често зависе од пропсова — на пример, ширина елемента се израчунава на основу величине екрана. useMemo омогућава израчунавање ових динамичких стилова само при промени улазних параметара.

Када је useMemo бескористан

useMemo није универзално средство оптимизације. У одређеним сценаријима не доноси добит и чак може погоршати перформансе због додатних трошкова чувања и поређења зависности. У React Native, где је сваки бајт меморије битан, слепа примена useMemo-а без мерења ефекта је антиобразац.

Хук не доноси корист у три главна случаја. Прво, ако је прорачун тривијалан (просто сабирање, конкатенација стрингова), трошкови useMemo-а премашују вредност самог прорачуна. Друго, ако се зависности мењају при сваком рендеровању — функција ће се ипак извршавати, а мемоизација ће додати само додатни посао. Треће, ако се компонента ретко рендерује, трошак чувања кеша није оправдан.

Према Kent C. Dodds, 2023, пре додавања useMemo-а потребно је измерити проблем помоћу React DevTools Profiler-а или уграђеног Performance Monitor-а у React Native. Ако поновно рендеровање компоненте траје мање од 1 ms, мемоизација није потребна.

  • Тривијални прорачуни — сабирање, конкатенација, једноставне тернарне операције
  • Ретка поновна рендеровања — статички екрани који се рендерују једном
  • Променљиве зависности — ако су зависности нове при сваком рендеровању, мемоизација је бескорисна
  • Примитивне вредности — бројеви и стрингови не захтевају мемоизацију, они су ионако јефтини

useMemo и useCallback: поређење

useMemo и useCallback — два хука мемоизације из React-а која се често мешају. Разлика је у томе шта чувају: useMemo враћа резултат извршавања функције (било коју вредност), а useCallback враћа саму функцију. Оба прихватају низ зависности, али синтакса се разликује.

КарактеристикаuseMemouseCallback
ВраћаРезултат извршавања функцијеРеференцу на функцију
Први аргументФункција која враћа вредностФункција за мемоизацију
Типична применаКеширање прорачунаСтабилни колбекови за компоненте деце
ЕквивалентностuseMemo(() => fn, deps)useCallback(fn, deps) === useMemo(() => fn, deps)

У пракси, useCallback је синтаксни шећер над useMemo-ом за случај када је потребно мемоизовати функцију. У React Native се оба хука користе подједнако често: useMemo — за податке (форматиран текст, израчунати стилови), useCallback — за руковаоце догађајима (onPress, onChangeText).

Практични примери са useMemo

Размотримо два стварна сценарија коришћења useMemo-а у React Native апликацијама. Први — филтрирање листе контаката по упиту претраге, други — израчунавање динамичких стилова на основу величине екрана.

Пример 1: претрага и филтрирање листе

У овом примеру useMemo спречава поновно филтрирање велике листе контаката при сваком рендеровању, ако се нису променили ни упит претраге ни изворни подаци.

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

Без useMemo-а, филтрирање би се извршавало при сваком рендеровању, укључујући она изазвана анимацијама или променом стања других делова компоненте. Са useMemo-ом, филтрирање се покреће само при промени contacts или searchQuery.

Пример 2: израчунавање динамичких стилова

У React Native стилови често зависе од величина екрана или пропсова компоненте. useMemo омогућава израчунавање таквог објекта стилова једном и поновно коришћење док се зависности не промене.

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

Овај приступ гарантује да објекат cardStyle остаје стабилан (иста референца) док се isSelected не промени. Ако је Card омотан у React.memo, овај образац спречава непотребна поновна рендеровања елемената деце.

Често постављана питања

Шта враћа useMemo?

useMemo враћа мемоизовану вредност — резултат извршавања функције прослеђене као први аргумент. При наредним рендеровањима React враћа сачувану вредност ако се зависности нису промениле.

По чему се useMemo разликује од useCallback-а?

useMemo враћа резултат извршавања функције (било коју вредност: број, објекат, JSX), а useCallback враћа саму функцију. Притом је useCallback(fn, deps) еквивалентан useMemo(() => fn, deps).

Када useMemo није потребан?

useMemo је бескористан код тривијалних прорачуна (сабирање, конкатенација), ретких поновних рендеровања, зависности које се мењају при сваком рендеровању и за примитивне типове. Увек мерите перформансе пре додавања useMemo-а.

Може ли useMemo погоршати перформансе?

Да, ако се користи без потребе. React чува претходне вредности у меморији и врши поређење зависности при сваком рендеровању. За једноставне прорачуне трошак ових операција премашује добит од мемоизације.

Како отклонити грешке у раду useMemo-а?

Користите React DevTools Profiler за мерење времена рендеровања компоненти. У React Native је такође доступан Performance Monitor преко менија за програмере. Ако поновно рендеровање траје мање од 1 ms — useMemo није потребан.

Закључци

  • useMemo — React хук за мемоизацију вредности, који кешира резултат функције између рендеровања
  • Хук прихвата функцију за израчунавање и низ зависности, поново израчунавајући вредност само при њиховој промени
  • У React Native useMemo је посебно важан за оптимизацију листи, анимација и сложених прорачуна
  • Кључни сценарији: скупи прорачуни, стабилни пропсови за React.memo, динамички стилови
  • useMemo се разликује од useCallback-а: први враћа вредност, други — функцију
  • Злоупотреба useMemo-а погоршава перформансе због додатних трошкова чувања и поређења зависности
  • Пре додавања useMemo-а увек мерите проблем путем React DevTools Profiler-а или Performance Monitor-а у React Native

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође