Herkese Merhabalar arkadaşlar! Bugün Angular dünyasının son zamanlarda en çok konuşulan konularından birine giriyoruz: Angular Signals. “Bir de bu mu çıktı” diyebilirsiniz, hatta “RxJS varken neden başka bir şeye ihtiyacımız var ki?” diye sorabilirsiniz. Endişelenmeyin — bu soruları birlikte cevaplayacağız ve yazının sonunda neden bu konuya heyecanlandığımı siz de anlayacaksınız.
Angular Signals Nedir?
Kısaca şöyle özetleyebiliriz: Signal, içindeki değer değiştiğinde bunu otomatik olarak ilgili tüm yerlere haber veren akıllı bir değer kabıdır. Bir değeri signal içine koyduğunuzda, o değer her değiştiğinde onu kullanan her yer — template olsun, başka bir hesaplama olsun — otomatik olarak güncellenir.
Bunu somutlaştırmak için günlük hayattan bir analoji düşünelim: Evinizde akıllı bir termostat var diyelim. Bu termostat sadece sıcaklığı göstermekle kalmıyor; sıcaklık değiştiğinde klimaya, ısıtıcıya ve telefon uygulamanıza eş zamanlı haber veriyor. Siz “klima güncelle” diye ayrıca bir şey yazmak zorunda değilsiniz — bağlantı otomatik. İşte Angular Signals tam olarak bu mantıkla çalışıyor: değer değişir, bağlı olan her şey haberdar olur.
Neden İhtiyaç Duyduk? Asıl Sorun Ne?
Angular, yıllarca Zone.js adlı bir kütüphane üzerinden change detection yapıyordu. Zone.js, tüm asenkron operasyonları — setTimeout, HTTP istekleri, click event’leri — yakalayarak Angular’a “hey, bir şeyler değişmiş olabilir, component tree’yi tara!” diyordu.
Bu yaklaşım işe yarıyordu, ancak ciddi bir maliyeti vardı: Angular her seferinde tüm component ağacını baştan sona tarayarak neyin değiştiğini bulmaya çalışıyordu. Uygulama küçükken bu fark edilmiyordu, ama yüzlerce component’e ulaştığında performans problemleri kaçınılmaz hale geliyordu.
Bir de şunu yaşadınız mı: OnPush change detection stratejisini kullandınız, her şeyi doğru yaptınız, ama ekran yine de güncellenmedi? Ya da tam tersi, ekran gereksiz yere defalarca render oldu? Malesef Zone.js tabanlı yaklaşımın bu tür sürprizleri zaman zaman karşınıza çıkıyordu. Angular Signals bu problemi kökünden çözüyor: artık Angular neyin değiştiğini tahmin etmek zorunda değil, çünkü zaten biliyor.
Nasıl Çalışır? Üç Temel Kavram
Angular Signals’ın temelinde üç kavram var: signal, computed ve effect. Bunları sırayla inceleyelim.
1. signal()
Bir signal, başlangıç değeri alan ve .set() ya da .update() metodlarıyla değiştirilebilen reaktif bir değerdir. Değeri okumak için signal adını fonksiyon gibi çağırırsınız — yani parantez koyarsınız.
import { signal } from '@angular/core';
const count = signal(0);
console.log(count()); // 0
count.set(5);
console.log(count()); // 5
count.update(val => val + 1);
console.log(count()); // 6
Şunu fark ettiniz mi? count() diye çağırıyoruz — parantez var. Bu, Angular’ın bu signal’a olan bağımlılığı otomatik olarak takip edebilmesi için kritik öneme sahip.
2. computed()
Computed, bir veya birden fazla signal’dan türetilen hesaplanmış bir değerdir. Bağımlı olduğu signal’lar değiştiğinde otomatik olarak yeniden hesaplanır. React’la çalıştıysanız useMemo‘ya, Vue’dan geliyorsanız computed property’e benzetebilirsiniz — aslında aynı fikrin Angular yorumu.
import { signal, computed } from '@angular/core';
const firstName = signal('Teoman');
const lastName = signal('Dev');
const fullName = computed(() => `${firstName()} ${lastName()}`);
console.log(fullName()); // "Teoman Dev"
firstName.set('Angular');
console.log(fullName()); // "Angular Dev" — otomatik güncellendi!
3. effect()
Effect, bir signal değiştiğinde yan etki (side effect) çalıştırmak için kullanılır. Loglama, localStorage’a yazma veya analytics event göndermek gibi işlemler için idealdir. Peki ne zaman kullanmamalıyız? Doğrudan state güncellemesi yapmak için effect kullanmaktan kaçının — bunun için computed() daha uygun bir seçimdir.
import { signal, effect } from '@angular/core';
const theme = signal('dark');
effect(() => {
console.log(`Tema değişti: ${theme()}`);
localStorage.setItem('theme', theme());
});
theme.set('light'); // "Tema değişti: light" — otomatik tetiklendi
Bu üç kavramı bir araya getirdiğinizde, Zone.js’e hiç ihtiyaç duymadan tamamen reactive bir uygulama yazabiliyorsunuz. Angular artık neyin değiştiğini tahmin etmek zorunda değil — graph üzerinden tam olarak biliyor.
Template’de Nasıl Kullanılır?
Angular Signals’ın template entegrasyonu da oldukça temiz. Component’inizde bir signal tanımlayıp doğrudan template’de kullanabilirsiniz:
@Component({
template: `
<p>Sayaç: {{ count() }}</p>
<button (click)="increment()">Artır</button>
`
})
export class CounterComponent {
count = signal(0);
increment() {
this.count.update(val => val + 1);
}
}
Angular, template içinde count() çağrısını gördüğünde bu signal’a olan bağımlılığı otomatik kaydediyor ve değer değişince yalnızca o bölümü güncelliyor — tüm component tree’yi değil. Küçük bir component’te bu fark belirsiz görünebilir, ama büyük uygulamalarda performans kazancını hissedebilirsiniz.
Ne Zaman Kullanmalıyız? Ne Zaman Kullanmamalıyız?
Angular Signals her derde deva değil. Bazı durumlar için mükemmel bir çözüm, bazı durumlar için ise alternatifler hâlâ çok daha güçlü.
Signals’ı tercih etmeniz gereken durumlar:
- Component içi yerel state yönetimi —
isLoading,selectedItem, sayaçlar gibi değerler - Birbirine bağımlı, türetilmiş hesaplamalar (
computed()ile) - Change detection performansını optimize etmek istediğinizde
- Zone.js bağımlılığını azaltmak ya da tamamen ortadan kaldırmak istediğinizde
RxJS ve Observable’ların hâlâ daha güçlü olduğu durumlar:
- HTTP istekleri ve asenkron veri akışları
- Debounce, throttle, combineLatest gibi karmaşık stream operasyonları
- WebSocket gibi sürekli veri akışı olan senaryolar
Aslında Angular ekibi bu iki dünyayı birbirine entegre etmek için toSignal() ve toObservable() helper fonksiyonlarını sunuyor. Dolayısıyla “ya Signals ya RxJS” diye zorlu bir seçim yapmak zorunda değilsiniz — ikisini birlikte kullanabilirsiniz ve çoğu zaman bu en pragmatik yaklaşım.
Öte yandan, uygulamanızın global state yönetimine ihtiyacı varsa ve büyük ölçekli bir proje geliştiriyorsanız, Angular NGXS gibi state management kütüphanelerini de göz ardı etmemelisiniz. Signals, NGXS’in rakibi değil — farklı katmanlardaki farklı problemleri çözüyorlar.
Angular 17 ve Sonrasına Bakış
Angular Signals, Angular 17 ile birlikte stable statüsüne kavuştu ve artık production kullanımı için tam anlamıyla öneriliyor. Angular ekibinin uzun vadeli yol haritasına bakıldığında, Zone.js’i opsiyonel hale getirip tamamen Signals tabanlı bir reactivity modeline geçiş planlandığı görülüyor. Yani bu sadece bir “yeni özellik” değil — Angular’ın geleceğinden bahsediyoruz.
Angular’ın Dependency Injection sistemi ve component mimarisi gibi temel konulara hâkimseniz, Signals’ı bu temelin üzerine inşa edilmiş doğal bir evrim olarak görebilirsiniz. Eğer lifecycle hook’larına henüz tam hâkim değilseniz, ngOnInit ve ngDoCheck yazılarıma da göz atmanızı öneririm — Signals’ın ne zaman ve neden tetiklendiğini anlamak için bu temeli bilmek işinizi kolaylaştırır.
Özet
Angular Signals, Zone.js’in “kör” change detection yaklaşımının yerini alan, daha performanslı ve öngörülebilir bir reactivity modelidir. signal() ile reaktif değer oluşturursunuz, computed() ile türetilmiş değerler hesaplarsınız, effect() ile değişikliklere tepki verirsiniz. Angular bu bağımlılıkları otomatik takip eder ve yalnızca gerçekten değişen yerleri günceller — gerisi sihir gibi kendi hallediliyor.
I believe Angular Signals, framework’ü çok daha modern ve öngörülebilir kılıyor. Zone.js’in sürprizlerinden yorulmuş biri olarak bu değişikliği gerçekten heyecanla karşılıyorum. Bir sonraki yazımda Signals’ı gerçek bir uygulama senaryosunda ele alacağız: HTTP istekleriyle toSignal() kullanımı ve RxJS ile Signals’ı nasıl birlikte yönetebileceğimizi inceleyeceğiz. Takipte kalın, arkadaşlar!