Skip to content
< samuelsantana.dev />
Back to the Blog

O Renascimento do Angular: Dominando Signals e a Nova Abordagem HTTP

Samuel Santana
Published on July 07, 2026
Angular

Se você acompanha o ecossistema Angular de perto, sabe que o framework está passando pelo seu maior renascimento desde a reescrita do AngularJS para o Angular 2. Com a chegada das versões 16 e 17, e a consolidação nas versões mais recentes (18 a 21), o Google mudou as regras do jogo.

O foco agora é claro: Developer Experience (DX), performance extrema e a redução drástica de boilerplate. E no centro dessa revolução estão duas peças fundamentais: os Signals e a modernização do HttpClient.

Neste artigo, vamos dissecar como essas ferramentas mudam a forma como arquitetamos aplicações escaláveis.

🚦 O que são Signals e por que você deveria se importar?

Durante anos, o Angular confiou no Zone.js para detectar mudanças. O problema? O Zone.js é uma "marreta". Ele intercepta eventos assíncronos (cliques, timeouts, requisições HTTP) e, na dúvida, verifica a árvore de componentes inteira para ver se algo mudou. Em aplicações complexas, como plataformas SaaS multi-tenant com painéis de dados densos, isso gera gargalos de performance.

Os Signals trazem a reatividade de grão fino (fine-grained reactivity). Um Signal é um wrapper ao redor de um valor que notifica os consumidores apenas quando esse valor realmente muda. O framework passa a saber exatamente qual nó do DOM precisa ser atualizado, sem depender do Zone.js.

Os 3 Pilares dos Signals:
  1. signal(): O estado mutável básico.
  2. computed(): Estado derivado puro. Ele só é recalculado se os Signals dos quais depende mudarem, e o valor é guardado em cache (memoizado).
  3. effect(): Efeitos colaterais (como manipular o DOM diretamente ou salvar no localStorage) que rodam automaticamente quando suas dependências mudam.

Exemplo prático de uso:

import { Component, signal, computed, effect } from '@angular/core';

@Component({
  selector: 'app-cart',
  standalone: true,
  template: `
    <div>
      <p>Quantidade: {{ quantity() }}</p>
      <p>Preço Total: {{ totalPrice() | currency }}</p>
      <button (click)="increment()">Adicionar Item</button>
    </div>
  `
})
export class CartComponent {
  // Estado básico
  quantity = signal(1);
  unitPrice = 50.00;

  // Estado derivado (só recalcula quando quantity mudar)
  totalPrice = computed(() => this.quantity() * this.unitPrice);

  constructor() {
    // Efeito colateral focado em observabilidade ou debug
    effect(() => {
      console.log(`O valor do carrinho mudou para: ${this.totalPrice()}`);
    });
  }

  increment() {
    this.quantity.update(q => q + 1);
  }
}
Casos de Uso e Vantagens
  • Vantagem Absoluta: Previsibilidade e performance. O fim do famigerado erro ExpressionChangedAfterItHasBeenCheckedError.
  • Casos de Uso: Gerenciamento de estado local complexo, formulários dinâmicos e interfaces de alta interatividade (como dashboards em tempo real).

🌐 A Nova Abordagem HTTP: Adeus Módulos, Olá Fetch API

Junto com a reatividade, a forma como o Angular lida com injeção de dependências e requisições de rede evoluiu. O antigo HttpClientModule está sendo deixado para trás na era dos Standalone Components.

A partir do Angular 15 (e consolidado como padrão no 17+), a recomendação é utilizar o provideHttpClient(). Mais do que uma mudança de sintaxe, essa nova API trouxe o withFetch().

O poder do withFetch()

Historicamente, o HttpClient usava a API XMLHttpRequest por baixo dos panos. Ao habilitar o withFetch(), o Angular passa a usar a Fetch API nativa dos navegadores modernos. Isso não apenas melhora a performance e reduz o tamanho do bundle, mas é um requisito vital se você está utilizando Server-Side Rendering (SSR) ou Static Site Generation (SSG), pois o Node.js lida muito melhor com o fetch nativo.

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withFetch } from '@angular/common/http';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withFetch()) // Simples, limpo e performático
  ]
};

🌉 Unindo os Dois Mundos: RxJS vs Signals

A pergunta que todo recrutador técnico ou Tech Lead faz hoje é: "Os Signals vão matar o RxJS?"

A resposta de um engenheiro sênior é: Não. Eles resolvem problemas diferentes.

O RxJS é excepcional para lidar com eventos assíncronos ao longo do tempo (como debouncing de inputs ou WebSockets). Já os Signals são perfeitos para estado síncrono. A beleza do Angular moderno está na interoperabilidade. Com o pacote @angular/core/rxjs-interop, podemos fazer requisições HTTP (que retornam Observables) e transformá-las em Signals de forma elegante com o toSignal:

import { Component, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { toSignal } from '@angular/core/rxjs-interop';

@Component({
  selector: 'app-user-profile',
  standalone: true,
  template: `
    @if (user()) {
      <h1>{{ user().name }}</h1>
    } @else {
      <p>Carregando...</p>
    }
  `
})
export class UserProfileComponent {
  private http = inject(HttpClient);
  
  // Transforma o Observable da requisição HTTP diretamente em um Signal
  user = toSignal(this.http.get<User>('/api/user/1'));
}

Nota: A nova sintaxe de Control Flow (@if, @for) do Angular 17+ combina perfeitamente com Signals.

Conclusão

A engenharia de software é sobre adotar os padrões corretos para resolver gargalos de escala. A migração mental para os Signals e o uso do novo HttpClient com Fetch API não são apenas "hype". São ferramentas tangíveis que reduzem a carga cognitiva do desenvolvedor, diminuem o tamanho da aplicação e entregam um produto final visivelmente mais rápido para o usuário. O Angular não está apenas acompanhando o mercado; ele está ditando uma nova forma de arquitetar o frontend.

Comments

Loading comments...