- Konu sahibi
- #1
React’te
Temizleme yapılmazsa eski efekt çalışmaya devam edebilir. Bunun sonucu olarak aynı olay birden fazla kez işlenebilir, gereksiz ağ istekleri sürebilir veya artık ekranda olmayan bir bileşen için işlem yapılabilir.
Bir efektin genel yapısı şöyledir:
React’in davranışı bağımlılık dizisine göre değişir:
Temizleme fonksiyonu yalnızca efekt gerçekten bir kaynak oluşturduğunda gerekir. Örneğin bir değeri hesaplayıp konsola yazan efektin kapatılacak bir kaynağı yoksa temizleme döndürmek zorunlu değildir.
Aşağıdaki bileşen, her saniye sayacı artıran bir zamanlayıcı kurar. Efekt yeniden çalıştığında veya bileşen kaldırıldığında
Uygulama adımları:
Sayaç interval callback sayısını gösterir; arka plan sekmesi ve yoğun ana iş parçacığı nedeniyle gerçek geçen süreye eşit olmak zorunda değildir. Başarı sonucu, bileşen mount edilmişken sayacın ilerlemesi ve bileşen kaldırıldıktan sonra yeni interval’ların çalışmamasıdır. Temizleme unutulursa bileşen görünür değilken de zamanlayıcı çalışabilir. Geliştirme ortamında Strict Mode kullanılıyorsa React kurulumu ve temizlemeyi art arda test edebilir; bu, temizleme fonksiyonunun güvenilir ve tekrar çağrılabilir yazılması gerektiğini gösteren bir geliştirme davranışıdır.
Efekt içinde oluşturduğunuz kaynağın karşılığını temizleme fonksiyonunda kullanın:
Yanlış kaynağı kapatmak: Her efekt kendi oluşturduğu kaynağın kimliğini veya referansını temizlemelidir. Ortak bir değişkeni yanlışlıkla değiştirmek, başka bir bileşenin zamanlayıcısını kapatabilir.
Bağımlılıkları eksik yazmak: Efekt içinde kullanılan değişken değişebiliyorsa bağımlılık dizisine uygun şekilde eklenmelidir. Aksi durumda efekt eski değeri görebilir veya eski abonelik çalışmaya devam edebilir.
Temizleme fonksiyonunda yeni kaynak oluşturmak: Temizleme bölümü yeni interval, dinleyici veya abonelik kurmamalıdır; amacı mevcut kaynağı kapatmaktır.
Her efektin mutlaka temizlenmesi gerektiğini düşünmek: Temizlenecek dış kaynak yoksa gereksiz bir fonksiyon eklemek sorunu çözmez. Önce efektin React dışındaki hangi kaynağı oluşturduğunu belirleyin.
Hayır. Temizleme fonksiyonunun amacı kaynakları kapatmaktır. State’in başlangıç değerine dönmesi, bileşenin yeniden oluşturulmasıyla ilgilidir.
Hayır. Yalnızca kapatılması veya iptal edilmesi gereken bir dış kaynak kuruyorsanız fonksiyon döndürün. Kaynak oluşturmayan efektlerde dönüş değeri gerekmeyebilir.
Böylece önceki bağımlılıklarla kurulmuş kaynak kapanır, ardından yeni bağımlılıklarla tek bir güncel kaynak kurulur. Bu düzen, eski aboneliklerin ve zamanlayıcıların birikmesini önler.
useEffect içinden döndürülen temizleme fonksiyonu, efektin oluşturduğu dış kaynakları ve abonelikleri artık kullanılmadığında kapatmak için kullanılır. Zamanlayıcıyı durdurmak, olay dinleyicisini kaldırmak, WebSocket bağlantısını kapatmak veya devam eden bir isteği iptal etmek buna örnektir. React bu fonksiyonu efekt yeniden çalışmadan önce ve bileşen DOM’dan kaldırılırken çağırır.Temizleme yapılmazsa eski efekt çalışmaya devam edebilir. Bunun sonucu olarak aynı olay birden fazla kez işlenebilir, gereksiz ağ istekleri sürebilir veya artık ekranda olmayan bir bileşen için işlem yapılabilir.
Nasıl çalışır?
Bir efektin genel yapısı şöyledir:
Kod:
useEffect(() => {
// Kurulum: dış kaynak oluşturulur
return () => {
// Temizleme: dış kaynak kapatılır
};
}, [bagimliliklar]);
React’in davranışı bağımlılık dizisine göre değişir:
| Bağımlılık | Temizleme ne zaman çalışır? | Tipik kullanım |
|---|---|---|
[] | Unmount sırasında; geliştirmede Strict Mode ek setup/cleanup sınaması da yapabilir | Tek seferlik abonelik veya zamanlayıcı |
| Değişkenler içeren dizi | Efekt yeniden çalışmadan önce ve kaldırılmada | Kimliği değişen veri aboneliği |
| Bağımlılık dizisi yok | Her yeniden çalışmadan önce ve kaldırılmada | Genellikle dikkatle kullanılmalıdır |
Temizleme fonksiyonu yalnızca efekt gerçekten bir kaynak oluşturduğunda gerekir. Örneğin bir değeri hesaplayıp konsola yazan efektin kapatılacak bir kaynağı yoksa temizleme döndürmek zorunlu değildir.
Somut örnek: interval temizlemek
Aşağıdaki bileşen, her saniye sayacı artıran bir zamanlayıcı kurar. Efekt yeniden çalıştığında veya bileşen kaldırıldığında
clearInterval zamanlayıcıyı durdurur:
Kod:
import { useEffect, useState } from "react";
export default function Sayac() {
const [sayi, setSayi] = useState(0);
useEffect(() => {
const intervalId = setInterval(() => {
setSayi((mevcut) => mevcut + 1);
}, 1000);
return () => {
clearInterval(intervalId);
};
}, []);
return <p>Zamanlayıcı adımı: {sayi}</p>;
}
Uygulama adımları:
- Bileşene ait dosyada
useEffectveuseStateiçe aktarılır. - Efekt içinde
setIntervalçağrılır ve dönen kimlikintervalIddeğişkeninde tutulur. - Efektin döndürdüğü fonksiyonda aynı kimlik
clearIntervalile kapatılır. - Bileşeni JSX ağacından kaldırarak (örneğin koşullu render ile) temizlemeyi gözlemleyin. Yalnızca CSS ile display:none vermek unmount değildir ve cleanup tetiklemez.
Sayaç interval callback sayısını gösterir; arka plan sekmesi ve yoğun ana iş parçacığı nedeniyle gerçek geçen süreye eşit olmak zorunda değildir. Başarı sonucu, bileşen mount edilmişken sayacın ilerlemesi ve bileşen kaldırıldıktan sonra yeni interval’ların çalışmamasıdır. Temizleme unutulursa bileşen görünür değilken de zamanlayıcı çalışabilir. Geliştirme ortamında Strict Mode kullanılıyorsa React kurulumu ve temizlemeyi art arda test edebilir; bu, temizleme fonksiyonunun güvenilir ve tekrar çağrılabilir yazılması gerektiğini gösteren bir geliştirme davranışıdır.
Hangi durumda ne temizlenir?
Efekt içinde oluşturduğunuz kaynağın karşılığını temizleme fonksiyonunda kullanın:
setIntervalveyasetTimeoutiçinclearIntervalveyaclearTimeoutçağırın.addEventListeneriçin aynı hedef, olay adı, işleyici referansı ve capture seçeneğiyleremoveEventListenerkullanın. İşleyiciyi temizleme içinde yeniden oluşturmayın; aynı fonksiyon referansını saklayın.- WebSocket veya benzeri bağlantılar için bağlantının API’sindeki kapatma yöntemini çağırın.
- Fetch isteği için efekt içinde
AbortControlleroluşturup temizlemedeabort()çağırın. İptal hatasını uygulamanın gerçek hata akışından ayrı ele alın; geç gelen sonuçları state’e yazmadan önce effect’in hâlâ geçerli olduğunu da kontrol edin. Abort isteği, sunucuda başlamış işlemi mutlaka geri almaz. - Harici bir mağaza veya kütüphane aboneliği için abonelikten çıkma işlevini çağırın.
Sık yapılan hatalar
Yanlış kaynağı kapatmak: Her efekt kendi oluşturduğu kaynağın kimliğini veya referansını temizlemelidir. Ortak bir değişkeni yanlışlıkla değiştirmek, başka bir bileşenin zamanlayıcısını kapatabilir.
Bağımlılıkları eksik yazmak: Efekt içinde kullanılan değişken değişebiliyorsa bağımlılık dizisine uygun şekilde eklenmelidir. Aksi durumda efekt eski değeri görebilir veya eski abonelik çalışmaya devam edebilir.
Temizleme fonksiyonunda yeni kaynak oluşturmak: Temizleme bölümü yeni interval, dinleyici veya abonelik kurmamalıdır; amacı mevcut kaynağı kapatmaktır.
Her efektin mutlaka temizlenmesi gerektiğini düşünmek: Temizlenecek dış kaynak yoksa gereksiz bir fonksiyon eklemek sorunu çözmez. Önce efektin React dışındaki hangi kaynağı oluşturduğunu belirleyin.
Kaynaklar
Sık sorulan sorular
Temizleme fonksiyonu bileşen kaldırılınca state’i sıfırlar mı?
Hayır. Temizleme fonksiyonunun amacı kaynakları kapatmaktır. State’in başlangıç değerine dönmesi, bileşenin yeniden oluşturulmasıyla ilgilidir.
useEffect içinden her zaman bir fonksiyon döndürmek gerekir mi?
Hayır. Yalnızca kapatılması veya iptal edilmesi gereken bir dış kaynak kuruyorsanız fonksiyon döndürün. Kaynak oluşturmayan efektlerde dönüş değeri gerekmeyebilir.
Temizleme fonksiyonu neden efekt yeniden çalışmadan önce çağrılır?
Böylece önceki bağımlılıklarla kurulmuş kaynak kapanır, ardından yeni bağımlılıklarla tek bir güncel kaynak kurulur. Bu düzen, eski aboneliklerin ve zamanlayıcıların birikmesini önler.