O hook useMemo no React Native memoiza o resultado de cálculos entre renderizações de componentes, prevenindo a execução repetida de operações custosas. Ao contrário do useCallback, que memoiza uma função, o useMemo preserva o valor retornado e o recalcula apenas quando as dependências especificadas mudam. De acordo com React Docs, 2024, a memoização é especialmente eficaz para cálculos com arrays grandes e transformações complexas de dados. No React Native, cada re-renderização desnecessária cria carga adicional na conexão ponte entre JavaScript e as threads nativas, portanto o uso correto do useMemo afeta diretamente a suavidade das animações e a velocidade de resposta da interface.
Principais pontos
useMemo — é um hook da biblioteca padrão do React, disponível no React Native sem pacotes adicionais. Ele memoiza o valor retornado pela função passada e reutiliza esse valor em renderizações subsequentes até que as dependências especificadas no array mudem.
O nome do hook vem de memoization — uma técnica de otimização onde o resultado de uma função custosa é armazenado em cache. Em chamadas subsequentes com os mesmos argumentos, o valor em cache é retornado em vez de ser recalculado.
No contexto do React Native, a memoização é especialmente importante devido às características arquiteturais. Cada re-renderização de componente envia dados através da ponte JavaScript — Nativo, o que leva tempo. Se um componente contém cálculos custosos (filtragem de lista, ordenação, formatação), cada re-renderização os repetirá, bloqueando a thread JS e causando queda de quadros.
De acordo com React Native Performance Docs, 2024, o gargalo geralmente não é a renderização de componentes nativos, mas a execução da lógica JavaScript entre as renderizações. O useMemo resolve precisamente esse problema.
useMemo recebe uma função e um array de dependências, retornando um valor memoizado. O React armazena o valor anterior e o array de dependências. Em cada renderização, o React compara as dependências atuais com as anteriores usando Object.is. Se pelo menos uma dependência mudou, a função é executada novamente e o resultado é armazenado.
A assinatura do useMemo é idêntica na web e no React Native. O primeiro argumento é uma função sem parâmetros que retorna o valor a ser memoizado. O segundo é um array de dependências, cujas mudanças farão o valor ser recalculado.
import React, { useMemo } from 'react';
const sortedList = useMemo(() => {
return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);
Neste exemplo, sortedList é recalculado apenas quando a referência ao array items muda. Se o conteúdo do array mudou mas a referência permaneceu a mesma (mutação), o useMemo não detectará as mudanças — esta é uma limitação importante.
O React usa o algoritmo Object.is para comparar dependências, que funciona de forma semelhante à igualdade estrita === mas lida corretamente com NaN (+0 e -0 são considerados diferentes). Isso significa que para tipos primitivos (strings, números, booleanos), a comparação funciona por valor, enquanto para objetos e arrays — por referência.
// Object.is({'a': 1}, {'a': 1}) -> false (different refs)
// Object.is(42, 42) -> true (primitive by value)
// Object.is(NaN, NaN) -> true (correct handling of NaN)
Entender este mecanismo é crítico: se você passar um novo objeto nas dependências a cada renderização, a memoização será inútil porque as dependências serão consideradas alteradas a cada vez.
useMemo é justificado em três cenários: cálculos custosos, passagem de props estáveis para componentes filhos e preservação da identidade referencial de objetos. No React Native, todos os três cenários ocorrem regularmente devido à arquitetura das aplicações móveis.
Se um componente processa arrays grandes de dados (filtragem, ordenação, agrupamento) ou operações matemáticas intensivas, o useMemo evita repetir esses cálculos a cada re-renderização. Em aplicações móveis, um exemplo típico é formatar dados de uma API antes de exibi-los em uma lista.
Quando um componente filho está envolto em React.memo, ele só re-renderiza quando suas props mudam. Se um objeto prop é criado dentro do pai sem useMemo, uma nova referência será criada a cada renderização do pai, e o componente filho re-renderizará desnecessariamente, anulando o benefício do React.memo.
No React Native, os estilos frequentemente dependem de props — por exemplo, a largura de um elemento é calculada com base no tamanho da tela. O useMemo permite calcular esses estilos dinâmicos apenas quando os parâmetros de entrada mudam.
useMemo não é uma ferramenta universal de otimização. Em vários cenários, ele não traz benefícios e pode até piorar o desempenho devido à sobrecarga de armazenar e comparar dependências. No React Native, onde cada byte de memória importa, aplicar useMemo cegamente sem medir seu efeito é um antipadrão.
O hook não traz benefícios em três casos principais. Primeiro, se o cálculo é trivial (adição simples, concatenação de strings), o custo do useMemo excede o custo do próprio cálculo. Segundo, se as dependências mudam a cada renderização — a função ainda será executada, e a memoização apenas adiciona trabalho extra. Terceiro, se o componente renderiza com pouca frequência, a sobrecarga de armazenamento em cache não é justificada.
De acordo com Kent C. Dodds, 2023, antes de adicionar useMemo, você deve medir o problema usando React DevTools Profiler ou o Monitor de Desempenho integrado no React Native. Se a re-renderização de um componente leva menos de 1 ms, a memoização não é necessária.
useMemo e useCallback — dois hooks de memoização do React que são frequentemente confundidos. A diferença está no que eles preservam: useMemo retorna o resultado da execução de uma função (qualquer valor), enquanto useCallback retorna a própria função. Ambos aceitam um array de dependências, mas a sintaxe difere.
| Característica | useMemo | useCallback |
|---|---|---|
| Retorna | Resultado da execução da função | Referência para a função |
| Primeiro argumento | Função que retorna um valor | Função a ser memoizada |
| Uso típico | Cache de cálculos | Callbacks estáveis para componentes filhos |
| Equivalência | useMemo(() => fn, deps) | useCallback(fn, deps) === useMemo(() => fn, deps) |
Na prática, useCallback é açúcar sintático sobre useMemo para os casos em que você precisa memoizar uma função. No React Native, ambos os hooks são usados com igual frequência: useMemo — para dados (texto formatado, estilos calculados), useCallback — para manipuladores de eventos (onPress, onChangeText).
Vejamos dois cenários reais de uso do useMemo em aplicações React Native. O primeiro é filtrar uma lista de contatos por consulta de busca, o segundo é calcular estilos dinâmicos com base no tamanho da tela.
Neste exemplo, o useMemo evita a filtragem repetida de uma lista grande de contatos a cada renderização se nem a consulta de busca nem os dados de origem mudaram.
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}
/>
);
};
Sem useMemo, a filtragem seria executada em cada renderização, incluindo aquelas causadas por animações ou mudanças de estado em outras partes do componente. Com useMemo, a filtragem é executada apenas quando contacts ou searchQuery mudam.
No React Native, os estilos frequentemente dependem das dimensões da tela ou das props do componente. O useMemo permite calcular esse objeto de estilos uma vez e reutilizá-lo até que as dependências mudem.
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>
);
};
Esta abordagem garante que o objeto cardStyle permaneça estável (mesma referência) até que isSelected mude. Se Card estiver envolto em React.memo, este padrão evita re-renderizações desnecessárias dos elementos filhos.
Perguntas frequentes
useMemo retorna um valor memoizado — o resultado da execução da função passada como primeiro argumento. Em renderizações subsequentes, o React retorna o valor em cache se as dependências não mudaram.
useMemo retorna o resultado da execução da função (qualquer valor: número, objeto, JSX), enquanto useCallback retorna a própria função. Note que useCallback(fn, deps) é equivalente a useMemo(() => fn, deps).
useMemo é inútil para cálculos triviais (adição, concatenação), re-renderizações infrequentes, dependências que mudam a cada renderização e tipos primitivos. Sempre meça o desempenho antes de adicionar useMemo.
Sim, se usado desnecessariamente. O React armazena valores anteriores em memória e compara dependências a cada renderização. Para cálculos simples, a sobrecarga dessas operações excede o benefício da memoização.
Use React DevTools Profiler para medir os tempos de renderização dos componentes. No React Native, o Monitor de Desempenho também está disponível através do menu do desenvolvedor. Se uma re-renderização leva menos de 1 ms — useMemo não é necessário.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também