Voltar para o Blog

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-compiler

Configuracao 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 manual

Checklist 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

📖 Ver Conteudo Completo

Comentários (0)

Esse artigo ainda não possui comentários 😢. Seja o primeiro! 🚀🦅

Adicionar comentário