Signals: a nova reatividade do Angular

Signals: a nova reatividade do Angular

Robson Rabelo - 12 de julho de 2026 - 0 visualizações

Em vez de varrer a árvore perguntando o que mudou, o dado avisa quem depende dele: signal, computed e effect explicados, o caminho zoneless e a convivência com RxJS.

Por uma década, o Angular respondeu à pergunta "algo mudou?" da forma mais cara possível: verificando tudo. A cada clique, timer ou resposta HTTP, a Zone.js acordava a detecção de mudanças e o framework revarria a árvore de componentes perguntando "e você, mudou?". Funciona, mas o custo cresce com o app.

Signals invertem a pergunta: em vez de o framework procurar o que mudou, o dado avisa exatamente quem depende dele. É a maior mudança do Angular moderno (angular.dev/guide/signals), e a base do futuro sem Zone.js.

As três peças

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

export class CarrinhoComponent {
  // signal: um valor reativo, lido como função
  itens = signal<Item[]>([]);

  // computed: deriva de outros signals, recalcula SÓ quando eles mudam
  total = computed(() =>
    this.itens().reduce((soma, i) => soma + i.preco * i.qtd, 0)
  );

  // effect: reage a mudanças (log, storage, integração)
  constructor() {
    effect(() => console.log("total mudou:", this.total()));
  }

  adicionar(item: Item) {
    this.itens.update((lista) => [...lista, item]); // imutável: nova referência
  }
}
<p>Total: {{ total() | currency: "BRL" }}</p>

Repare no modelo mental: signal é o estado, computed é a derivação, effect é a consequência. Quando itens muda, só total recalcula, e só o pedaço do template que lê total() atualiza. Nada de varrer a árvore: o grafo de dependências é rastreado automaticamente na leitura.

Por que isso importa (além da sintaxe)

  • Performance por construção: a atualização é cirúrgica. O componente que não depende do que mudou não é tocado, sem precisar de OnPush e truques de referência.
  • O caminho zoneless: com signals, o Angular sabe o que mudou sem a Zone.js interceptar o mundo. Aplicações provideZonelessChangeDetection() ficam mais leves, com stack traces limpos e menos mágica.
  • Derivações declaradas: aquele valor que era recalculado em três lugares (ou guardado dessincronizado) vira um computed, impossível de esquecer de atualizar.
  • Menos RxJS onde RxJS doía: estado síncrono de UI não precisa mais de BehaviorSubject + async pipe. Como vimos no artigo anterior, RxJS fica com o que é dele: eventos assíncronos no tempo.

Componentes conversando por signals

A família completa substitui os decorators clássicos com tipagem e reatividade melhores:

export class ProdutoCard {
  produto = input.required<Produto>();     // @Input reativo e obrigatório
  favoritado = output<string>();           // @Output

  desconto = computed(() =>                // deriva direto do input
    this.produto().preco * 0.9
  );
}

E o formulário simples fica direto com model() (two-way binding) e a ponte com o mundo RxJS é oficial: toSignal(obs$) e toObservable(sig) deixam o fluxo complexo viver em RxJS enquanto o template consome um signal.

Signals: o grafo que atualiza só quem depende

As regras que evitam os tropeços

  1. Mutação não dispara nada. this.itens().push(item) muda o array por dentro e ninguém fica sabendo. Sempre set/update com nova referência.
  2. computed é puro. Nada de efeitos colaterais dentro dele; é cálculo, não ação.
  3. effect é raro. Se você está setando um signal dentro de um effect, provavelmente queria um computed. Efeitos são para o mundo externo (log, localStorage, bibliotecas imperativas).
  4. Migração incremental: signals convivem com o código clássico. Comece pelos componentes de estado local e pelas derivações duplicadas; não é uma reescrita.

Signals ou RxJS? (o resumo da convivência)

  • Estado e derivações da UI (contadores, seleções, formulários simples, totais): signals.
  • Eventos ao longo do tempo (HTTP com cancelamento, debounce de busca, websocket, combinação de fontes): RxJS, entregando na fronteira via toSignal.

Times que adotam essa divisão relatam componentes menores, menos assinaturas para gerenciar e uma curva de entrada mais suave para quem chega. Planejar essa migração (o que vira signal primeiro, como medir o ganho) é trabalho que fazemos no serviço de Desenvolvimento Web, Mobile e Desktop.

Seu app Angular ainda depende de Zone.js para tudo? Descreva um componente pesado para a IA da Rabelo Digital, aqui no canto da tela, e ela esboça a versão com signals. Sem formulário, sem espera.


Leia também

Compartilhar:

Deixe um Comentário

Categorias

Posts Recentes