Bu hata NG0500 hatasına benzerdir, ancak Angular hidrasyon sürecinin DOM'da belirli bir noktada daha fazla kardeş düğüm beklediği ve bunları bulamadığı anlamına gelir. Doğrudan DOM manipülasyonuyla ilgili nedenler için NG0500 hatası sayfasına bakın.
Yaygın bir neden: sunucu ve istemci arasında farklılık gösteren koşullu içerik
Doğrudan DOM manipülasyonunun yanı sıra, bu hata çoğunlukla @if veya @for içindeki içerik sunucuda, istemcinin hidrasyon sırasında oluşturduğundan farklı render edildiğinde ortaya çıkar. Sunucu bir koşulu true olarak (veya bir listeyi daha fazla öğeyle) render ettiyse, ancak hidrasyon çalıştığında istemci bunu false olarak (veya daha kısa bir liste olarak) görüyorsa, istemci sunucunun gerçekte gönderdiğinden daha az kardeş düğüm bekler. Bu durumda hidrasyon, kardeşler arasında ilerlerken başarısız olur.
Bunun yaygın bir yolu, bir değerin bir input()'tan gelmesi, ancak bu input'u doğrudan (veya computed() aracılığıyla) kullanmak yerine ngOnInit() veya constructor içinde bir kez düz bir signal()'e kopyalanmasıdır:
@Component({
selector: 'app-example',
template: `
@if (visibleItems().length) {
<ul>
@for (item of visibleItems(); track item) {
<li>{{ item }}</li>
}
</ul>
}
`,
})
export class Example {
items = input<string[]>();
// Bu yalnızca bir kez çalışır. `ngOnInit` tam olarak çalıştığı anda
// `items()` henüz hazır değilse, bu sinyal sunucuda istemcidekinden
// farklı bir değer tutabilir. Bu da her iki tarafta farklı sayıda
// DOM düğümünün render edilmesi anlamına gelir ve bir hidrasyon
// uyumsuzluğuna neden olur.
visibleItems = signal<string[]>([]);
ngOnInit() {
this.visibleItems.set(this.items() ?? []);
}
}
Çözüm, değeri bir kez kopyalamak yerine türetmektir. Böylece ilki de dahil olmak üzere her render her zaman input ile eşleşir:
export class Example {
items = input<string[]>();
visibleItems = computed(() => this.items() ?? []);
}
Kullanıcıların bu değeri yerel olarak geçersiz kılmasına da izin vermeniz gerekiyorsa (örneğin ek öğeleri gösteren bir "daha fazla göster" düğmesi), bir yaşam döngüsü kancasından ayarlanan düz bir signal() yerine linkedSignal() kullanın.
Hatayı ayıklama
Doğrudan DOM manipülasyonuyla ilgili nedenleri ayıklamaya yönelik ipuçları için NG0500 hatasına bakın.
Bu hata tek başına hangi bileşenin buna neden olduğunu söylemez. Angular DevTools tarayıcı uzantısı yardımcı olabilir: hidrasyon uyumsuzluğunun gerçekleştiği bileşeni tam olarak vurgulayabilir. Bileşeni bulduktan sonra, şablonundaki bir @if veya @for içinde kullanılan herhangi bir değeri nasıl hesapladığına bakın. Bu değerin doğrudan bir input()'tan (bir şablon bağlaması veya computed() aracılığıyla) mı geldiğini, yoksa yukarıda gösterildiği gibi bir yaşam döngüsü kancası içinde bir sinyale mi kopyalandığını kontrol edin.