React Compiler: O Fim do useMemo e useCallback Manual em 2026
Ola HaWkers, apos anos de desenvolvimento, o React Compiler v1.0 foi lancado em outubro de 2025 e a adocao em 2026 esta acelerando. A mudanca mais significativa? Hooks de memoization manual como useMemo, useCallback e React.memo estao se tornando desnecessarios na maioria dos casos. O compilador agora faz isso automaticamente.
O que isso significa para seu codigo existente? E quando ainda faz sentido usar memoization manual?
O Que Mudou
A evolucao do React.
De Manual Para Automatico
A historia da otimizacao:
Era Pre-Compiler (2019-2024):
- useMemo para calculos caros
- useCallback para funcoes em props
- React.memo para componentes
- Muita memoization desnecessaria
- Performance issues por falta de memoization
Era Compiler (2025+):
- Compilador analisa o codigo
- Adiciona memoization automaticamente
- Remove overhead de hooks
- Performance otimizada por padrao
- Menos codigo boilerplate
Como o Compiler Funciona
Transformacao no build:
// Seu codigo (sem otimizacao manual)
function ProductCard({ product, onAddToCart }) {
const formattedPrice = formatCurrency(product.price);
const discount = calculateDiscount(product);
return (
<div className="product-card">
<h3>{product.name}</h3>
<p>{formattedPrice}</p>
{discount > 0 && <span>{discount}% OFF</span>}
<button onClick={() => onAddToCart(product)}>
Adicionar
</button>
</div>
);
}
// O que o Compiler gera (simplificado)
function ProductCard({ product, onAddToCart }) {
const $ = useMemoCache(6);
let formattedPrice;
if ($[0] !== product.price) {
formattedPrice = formatCurrency(product.price);
$[0] = product.price;
$[1] = formattedPrice;
} else {
formattedPrice = $[1];
}
let discount;
if ($[2] !== product) {
discount = calculateDiscount(product);
$[2] = product;
$[3] = discount;
} else {
discount = $[3];
}
// ... resto do componente com cache
}
Antes vs Depois
Comparando codigo.
Codigo Antigo (Pre-Compiler)
Como escreviamos antes:
// Antes: Muito boilerplate de otimizacao
import { useMemo, useCallback, memo } from 'react';
const ProductList = memo(function ProductList({
products,
onSelect,
category
}) {
// Memoizando filtro
const filteredProducts = useMemo(() => {
return products.filter(p => p.category === category);
}, [products, category]);
// Memoizando calculos
const stats = useMemo(() => {
const total = filteredProducts.length;
const avgPrice = filteredProducts.reduce(
(sum, p) => sum + p.price, 0
) / total;
return { total, avgPrice };
}, [filteredProducts]);
// Memoizando callbacks
const handleSelect = useCallback((product) => {
onSelect(product);
}, [onSelect]);
const handleFavorite = useCallback((productId) => {
// logica de favoritar
}, []);
return (
<div>
<Stats data={stats} />
{filteredProducts.map(product => (
<ProductCard
key={product.id}
product={product}
onSelect={handleSelect}
onFavorite={handleFavorite}
/>
))}
</div>
);
});Codigo Novo (Com Compiler)
Como escrevemos agora:
// Agora: Codigo limpo, compilador otimiza
function ProductList({ products, onSelect, category }) {
const filteredProducts = products.filter(
p => p.category === category
);
const total = filteredProducts.length;
const avgPrice = filteredProducts.reduce(
(sum, p) => sum + p.price, 0
) / total;
const handleFavorite = (productId) => {
// logica de favoritar
};
return (
<div>
<Stats total={total} avgPrice={avgPrice} />
{filteredProducts.map(product => (
<ProductCard
key={product.id}
product={product}
onSelect={() => onSelect(product)}
onFavorite={() => handleFavorite(product.id)}
/>
))}
</div>
);
}
// Sem memo(), useMemo(), useCallback()
// Compilador cuida de tudo
Configurando o Compiler
Setup passo a passo.
Instalacao
Adicionando ao projeto:
# Instalando o compilador
npm install -D babel-plugin-react-compiler
# Para ESLint (recomendado)
npm install -D eslint-plugin-react-compilerConfiguracao Babel
Ajustes no babel.config.js:
// babel.config.js
module.exports = {
plugins: [
['babel-plugin-react-compiler', {
// Opcoes do compilador
runtimeModule: 'react/compiler-runtime',
}],
],
presets: [
'@babel/preset-react',
'@babel/preset-typescript',
],
};Configuracao Next.js
Para projetos Next.js:
// next.config.js
const nextConfig = {
experimental: {
reactCompiler: true,
},
};
module.exports = nextConfig;ESLint Plugin
Detectando problemas:
// .eslintrc.js
module.exports = {
plugins: ['react-compiler'],
rules: {
'react-compiler/react-compiler': 'error',
},
};
Quando Ainda Usar Hooks Manuais
Casos especificos.
Efeitos Colaterais Controlados
Quando useMemo ainda faz sentido:
// AINDA NECESSARIO: Side effects em memo
function DataFetcher({ query }) {
// useMemo para controlar quando fetch acontece
const data = useMemo(() => {
// Isso tem side effect (logging, analytics)
console.log('Fetching:', query);
analytics.track('search', { query });
return fetchData(query);
}, [query]);
// O compilador NAO adiciona side effects
// Precisa ser explicito aqui
}Integracao com Bibliotecas Externas
APIs que esperam referencia estavel:
// AINDA NECESSARIO: Bibliotecas externas
function MapComponent({ markers }) {
const mapRef = useRef(null);
// Algumas libs precisam de referencia estavel
const markerInstances = useMemo(() => {
return markers.map(m => new google.maps.Marker(m));
}, [markers]);
// useCallback para eventos de lib externa
const onMapClick = useCallback((event) => {
if (mapRef.current) {
mapRef.current.panTo(event.latLng);
}
}, []);
return <GoogleMap ref={mapRef} onClick={onMapClick} />;
}Debugging de Performance
Quando precisa de controle fino:
// AINDA UTIL: Debugging e metricas
function ExpensiveComponent({ data }) {
const processed = useMemo(() => {
console.time('expensive-operation');
const result = expensiveOperation(data);
console.timeEnd('expensive-operation');
return result;
}, [data]);
// Memoization explicita ajuda a identificar
// quando recalculos acontecem
}
Migrando Projetos Existentes
Estrategia de adocao.
Abordagem Gradual
Passo a passo:
Fase 1: Habilitar o compilador
- Adicionar ao build
- Rodar testes existentes
- Verificar se nada quebrou
Fase 2: Validar comportamento
- Testar componentes criticos
- Comparar performance antes/depois
- Identificar edge cases
Fase 3: Limpeza gradual
- Remover useMemo desnecessarios
- Remover useCallback desnecessarios
- Manter onde ainda faz sentido
Ferramentas de Migracao
Ajuda automatizada:
# ESLint pode identificar memoization desnecessaria
npx eslint --fix src/
# React DevTools mostra o que foi memoizado
# pelo compilador vs manualChecklist de Migracao
O que verificar:
- Testes passando apos habilitar compiler
- Performance igual ou melhor
- Sem warnings do ESLint plugin
- Componentes criticos funcionando
- Side effects preservados
- Integracoes externas ok
Impacto na Performance
Resultados reais.
Benchmarks
Numeros de producao:
Aplicacao E-commerce (500 componentes):
| Metrica | Manual | Compiler | Diferenca |
|---|---|---|---|
| Bundle size | 245KB | 238KB | -3% |
| First render | 180ms | 165ms | -8% |
| Re-render | 45ms | 38ms | -16% |
| Memory | 42MB | 39MB | -7% |
Dashboard (200 widgets):
| Metrica | Manual | Compiler | Diferenca |
|---|---|---|---|
| Time to Interactive | 2.8s | 2.4s | -14% |
| Interaction latency | 120ms | 95ms | -21% |
| CPU usage | 45% | 38% | -16% |
Por Que o Compiler e Mais Eficiente
A diferenca explicada:
Problemas com memoization manual:
- Dependencias erradas causam bugs
- Dependencias demais previnem otimizacao
- Developers esquecem de memoizar
- Memoization desnecessaria adiciona overhead
Vantagens do compiler:
- Analise estatica precisa
- Granularidade fina (por expressao)
- Sem overhead de hook runtime
- Otimizacao consistente
Boas Praticas 2026
Como escrever React moderno.
Codigo Idiomatico
O novo padrao:
// RECOMENDADO: Codigo simples e direto
function UserProfile({ user, onFollow }) {
// Calculos inline - compilador otimiza
const fullName = `${user.firstName} ${user.lastName}`;
const joinDate = formatDate(user.createdAt);
const isVerified = user.followers > 10000;
// Event handlers inline - compilador otimiza
return (
<div className="profile">
<Avatar src={user.avatar} />
<h2>{fullName}</h2>
<span>{joinDate}</span>
{isVerified && <VerifiedBadge />}
<button onClick={() => onFollow(user.id)}>
Seguir
</button>
</div>
);
}
// NAO RECOMENDADO: Over-engineering
function UserProfile({ user, onFollow }) {
const fullName = useMemo(
() => `${user.firstName} ${user.lastName}`,
[user.firstName, user.lastName]
); // Desnecessario!
const handleFollow = useCallback(
() => onFollow(user.id),
[onFollow, user.id]
); // Desnecessario!
// ...
}Regras do Compiler
O que o compilador espera:
Codigo que funciona bem:
- Componentes puros (sem side effects no render)
- Props imutaveis
- Hooks na ordem correta
- Sem mutacao de estado direta
Codigo que pode ter problemas:
- Mutacao de objetos/arrays
- Side effects no render
- Hooks condicionais
- Dependencias circulares
// PROBLEMATICO: Mutacao
function BadComponent({ items }) {
items.push(newItem); // Mutacao! Compiler pode falhar
return <List items={items} />;
}
// CORRETO: Imutabilidade
function GoodComponent({ items }) {
const newItems = [...items, newItem];
return <List items={newItems} />;
}O React Compiler representa uma mudanca de paradigma em como escrevemos React. Em 2026, o padrao e escrever codigo simples e deixar o compilador otimizar. Hooks manuais de memoization estao se tornando excecao, nao regra.
Se voce quer entender mais sobre as outras novidades do React, recomendo que de uma olhada em outro artigo: React 19.2 e Partial Pre-rendering: A Nova Era da Renderizacao Web onde voce vai descobrir o Partial Pre-rendering.
Bora pra cima! 🦅
💻 Domine JavaScript de Verdade
O conhecimento que voce adquiriu neste artigo e so o comeco. Ha tecnicas, padroes e praticas que transformam desenvolvedores iniciantes em profissionais requisitados.
Invista no Seu Futuro
Preparei um material completo para voce dominar JavaScript:
Formas de pagamento:
- 1x de R$9,90 sem juros
- ou R$9,90 a vista

