Fala, comunidade dev! đź‘‹
Na nossa jornada modernizando um sistema corporativo de 5 anos (do Angular 16 para o 21), já limpamos o app.module.ts, modernizamos as rotas, abraçamos o inject() e enxugamos o HTML. Mas existe um fantasma que assombra projetos legados: os vazamentos de memória (memory leaks).
Em sistemas pesados com dezenas de formulários e grids, assinar eventos do RxJS (subscribe) sem limpá-los no ngOnDestroy é o caminho mais rápido para travar o navegador do usuário. Hoje, vamos ver como os Signals mudaram o jogo da reatividade, especialmente lidando com Formulários Reativos.
1. O Fantasma do RxJS em Formulários
Sistemas Enterprise tĂŞm formulários gigantescos. Imagine uma tela de cadastro com dezenas de campos, onde a mudança de uma opção (como selecionar "Pessoa JurĂdica") dispara validações ou desabilita outras partes da tela.
No Angular 16, ouvĂamos essas mudanças assim:
O Antes (Poluição visual e risco de vazamento):
@Component({ ... })
export class CadastroComponent implements OnInit, OnDestroy {
private destroy$ = new Subject<void>();
formulario: FormGroup;
ngOnInit() {
// Ouve as mudanças do formulário
this.formulario.get('tipoEntidade')?.valueChanges
.pipe(takeUntil(this.destroy$)) // O boilerplate de sempre...
.subscribe(valor => {
this.atualizarRegrasDeTela(valor);
});
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
}
A Bomba-Relógio: Multiplique esse boilerplate por 50 telas. É código repetitivo, propenso a falhas (quem nunca esqueceu um
takeUntilou esqueceu de implementar ongOnDestroy?) e difĂcil de ler. Um Ăşnicosubscribeesquecido aberto fica rodando na memĂłria RAM do navegador para sempre, mesmo apĂłs o usuário trocar de tela.
2. A Revolução dos Signals nos Formulários
Os Signals (signal(), computed(), effect()) introduziram uma reatividade sĂncrona, granular e livre de inscrições manuais. O Angular 21 permite transformar Observables (como o valueChanges do seu form) diretamente em Signals usando a função toSignal.
Olha como o mesmo cĂłdigo fica agora, sem implementar interfaces de ciclo de vida e sem o famigerado ngOnDestroy:
O Depois (Reativo, Limpo e Seguro):
@Component({ ... })
export class CadastroComponent {
private fb = inject(FormBuilder);
formulario = this.fb.group({
tipoEntidade: ['']
});
// Transforma o Observable em um Signal reativo!
tipoEntidadeSignal = toSignal(this.formulario.get('tipoEntidade')!.valueChanges);
constructor() {
// Reage automaticamente às mudanças. O Angular destrói isso sozinho!
effect(() => {
const valor = this.tipoEntidadeSignal();
if (valor !== undefined) {
this.atualizarRegrasDeTela(valor);
}
});
}
}
A Mágica por baixo dos panos: O
toSignalautomaticamente se inscreve no Observable e, o mais importante, cancela a inscrição sozinho quando o componente Ă© destruĂdo. Oeffectrastreia suas dependĂŞncias e sĂł executa quando o valor realmente muda. Adeus, memory leaks!
ConclusĂŁo
NĂłs nĂŁo abandonamos o RxJS. Ele continua sendo o rei absoluto para chamadas HTTP e fluxos assĂncronos complexos baseados em eventos no tempo. Mas para gerenciamento de estado local da tela e formulários, os Signals removeram toneladas de cĂłdigo inĂştil do nosso projeto. O cĂłdigo ficou previsĂvel, fácil de testar e livre de vazamentos de memĂłria.
No prĂłximo artigo (Parte 6), vamos falar sobre o impacto direto dessa reatividade sĂncrona: a possibilidade de finalmente desligarmos o motor antigo do Angular que causava tantos gargalos de performance, o zone.js. Vamos falar sobre o Zoneless Angular!
Você já começou a refatorar seus formulários velhos para usar Signals e toSignal? Conta aà a sua experiência! 👇
Top comments (0)