À medida que aplicações React crescem em complexidade, é natural que surjam gargalos de desempenho — principalmente em componentes que realizam re-renderizações frequentes ou lidam com dados e funções pesadas. Felizmente, a própria biblioteca React oferece ferramentas para mitigar esses problemas. Neste artigo, vamos explorar duas dessas ferramentas poderosas: useMemo
e useCallback
.
Por que se preocupar com otimização?
O React é muito eficiente em seu processo de renderização, mas isso não significa que todo re-render seja barato. Componentes filhos que dependem de props que mudam constantemente, cálculos pesados realizados a cada render ou funções recriadas desnecessariamente podem prejudicar a performance da aplicação — especialmente em dispositivos móveis ou em projetos com muitos dados dinâmicos.
useMemo
****: memorizando valores computados
useMemo
é um hook que memoriza o resultado de uma função “pesada” para evitar que ela seja recalculada desnecessariamente.
Sintaxe:
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
Esse hook só irá reexecutar a função computeExpensiveValue
quando a
ou b
mudarem.
Exemplo prático:
Imagine uma lista de usuários com um filtro por nome. Cada vez que digitamos no campo de busca, a lista é recalculada:
const filteredUsers = useMemo(() => { return users.filter((user) => user.name.includes(searchTerm)); }, [users, searchTerm]);
Sem o useMemo
, essa filtragem aconteceria em toda renderização, mesmo que users
ou searchTerm
não tivessem mudado.
useCallback
****: memorizando funções
Enquanto useMemo
serve para memorizar valores, useCallback
memoriza funções. Isso é especialmente útil quando passamos funções como props para componentes filhos otimizados com React.memo
.
Sintaxe:
const memoizedCallback = useCallback(() => { doSomething(a, b); }, [a, b]);
A função só será recriada se a
ou b
mudarem.
Exemplo prático:
const handleClick = useCallback(() => { console.log("Botão clicado!"); }, []);
Se handleClick
for passado para um botão dentro de um componente filho que usa React.memo
, ele não causará um novo render sempre que o componente pai for atualizado — desde que a função não mude.
Quando usar?
Evite cair na armadilha de otimizar tudo prematuramente. Use useMemo
e useCallback
quando:
- Você identificou um gargalo de performance real.
- O cálculo é complexo ou a função é recriada constantemente.
- Você está trabalhando com listas, filtros ou callbacks passados para componentes filhos.
Conclusão
React oferece ferramentas eficazes para melhorar o desempenho da aplicação, e useMemo
e useCallback
são duas delas. Quando usados com propósito e estratégia, podem evitar re-renderizações desnecessárias e tornar a experiência do usuário muito mais fluida.
Se você está desenvolvendo aplicações de alto desempenho com React, considere integrar essas boas práticas no seu dia a dia. Pequenas otimizações podem ter um grande impacto no resultado final.