Explorando Signals no Angular: Signal, Input Signal, Writable Signal, Effect e Computed
- Signals | Angular
Se rodar o comando ng generate @angular/core:signals
- Transformar @Input em Signals;
- Transformar @ViewChild e @ViewChildren em Signals;
- Transformar @ContentChild e @ContentChildren em Signals
Introdução aos Signals no Angular
O Angular sempre foi conhecido pelo seu sistema de detecção de mudanças, que historicamente dependia do Zone.js. No entanto, essa abordagem pode ser ineficiente, pois exige que a árvore inteira de componentes seja verificada sempre que há uma atualização.
Para resolver esse problema, o Angular introduziu os Signals, um novo modelo reativo que melhora o desempenho, eliminando verificações desnecessárias e atualizando apenas os elementos da interface afetados.
Os Signals são funções que retornam um valor e notificam os consumidores sempre que esse valor muda. Eles permitem um gerenciamento de estado reativo de forma mais eficiente e previsível, substituindo abordagens baseadas em RxJS para muitos casos.
Signal (Writable Signal)
O Writable Signal (signal()) é o tipo mais básico de Signal, que pode armazenar valores mutáveis e notificar automaticamente quando há mudanças.
Criando um Writable Signal
import { signal } from '@angular/core';
export class CounterComponent {
count = signal(0); // Criando um signal com valor inicial
increment() {
this.count.set(this.count() + 1); // Atualizando o valor do signal
}
}
Métodos disponíveis em um Writable Signal
| Método | Descrição |
|---|---|
set(value: T) | Define um novo valor para o Signal e notifica os consumidores. |
update(updateFn: (value: T) => T) | Atualiza o valor do Signal baseado no estado atual. |
Exemplo de uso do método update()
this.count.update(c => c + 1); // Atualiza o valor do signal incrementando 1
Input Signal
O Input Signal (@input() signal()) permite que um componente filho receba um valor reativo de um componente pai, mantendo a reatividade automaticamente.
Exemplo de um Input Signal
import { Component, input, signal } from '@angular/core';
@Component({
selector: 'app-child',
template: `<p>Valor recebido: {{ valor() }}</p>`,
})
export class ChildComponent {
@input() valor = signal(0); // O valor será atualizado automaticamente quando o pai mudar
}
No componente pai, podemos passar um valor dinâmico:
<app-child [valor]="count"></app-child>
Os Input Signals tornam os dados fluídos entre componentes sem a necessidade de OnPush ou ChangeDetectionRef.
Computed Signal
O Computed Signal (computed()) é um Signal que depende de outros Signals e recalcula automaticamente seu valor sempre que alguma dependência muda.
Exemplo de Computed Signal
import { computed, signal } from '@angular/core';
export class CounterComponent {
count = signal(5);
// Computed Signal: Sempre reflete o dobro do count
doubleCount = computed(() => this.count() * 2);
}
Características do Computed Signal
- Seu valor é calculado a partir de outros Signals.
- Se atualiza automaticamente quando os Signals dependentes mudam.
- Não pode ser atualizado manualmente (
seteupdatenão estão disponíveis).
Effect Signal
O Effect Signal (effect()) é usado para executar efeitos colaterais (como logs, chamadas HTTP ou atualizações no DOM) sempre que um Signal muda.
Exemplo de uso do Effect Signal
import { effect, signal } from '@angular/core';
export class GameComponent {
jogos = signal(['Baldur’s Gate III', 'Elden Ring']);
constructor() {
effect(() => {
console.log(`Número de jogos: ${this.jogos().length}`);
});
}
adicionarJogo(novoJogo: string) {
this.jogos.update(j => [...j, novoJogo]); // Atualiza a lista de jogos
}
}
Funcionamento do Effect Signal
- Sempre que o Signal dependente (
jogos) mudar, a função dentro deeffect()será reexecutada. - Útil para monitoramento, sincronizações ou operações assíncronas.
Resumo dos Tipos de Signals no Angular
| Tipo | Função |
|---|---|
signal() (Writable Signal) | Cria um Signal mutável, permitindo leitura e escrita. |
@input() signal() (Input Signal) | Permite passar um Signal como propriedade de um componente pai para um filho. |
computed() (Computed Signal) | Cria um Signal derivado, recalculando automaticamente quando seus dependentes mudam. |
effect() (Effect Signal) | Executa efeitos colaterais sempre que um Signal muda. |
Conclusão
Os Signals revolucionam a forma como o Angular gerencia estado e reatividade, eliminando verificações desnecessárias e garantindo um desempenho superior. Eles oferecem uma alternativa eficiente ao Zone.js e, em muitos casos, reduzem a necessidade de RxJS.
Se você está desenvolvendo aplicações modernas com Angular, incorporar Signals pode tornar seu código mais performático, fácil de manter e reativo.
Signal x Observables
O Signal é usado mais para estado dentro do componente, enquanto o Observable trabalha com eventos, http, etc