useEffect: nedir, yan etki hook'u ve React'te yaşam döngüsü

Yazar: IT Sectr Yayınlanma: 2026-07-04 Okuma süresi: 9 dk

useEffect, fonksiyonel bileşenlerde yan etkileri gerçekleştirmenizi sağlayan bir React hook'udur ve sınıf bileşenlerinin yaşam döngüsü yöntemlerini (componentDidMount, componentDidUpdate ve componentWillUnmount) değiştirir. React Documentation (2025)'a göre useEffect, React DOM'da değişiklikleri commit ettikten sonra çalışır ve gerçek DOM ağacına erişim sağlar. Hook, bir efekt işlevi ve yürütme sıklığını kontrol eden isteğe bağlı bir bağımlılık dizisi alır.

Önemli Noktalar

  • useEffect, bileşen render edildikten sonra yan etkileri gerçekleştirmek için bir hook'tur.
  • Bağımlılık dizisi, efektin ne zaman yeniden çalışacağını kontrol eder; boş dizi = bir kez.
  • Temizlik — efektin temizleme işlevi, demonte etme sırasında ve yeniden çalıştırmadan önce çağrılır.
  • Yaşam döngüsü — componentDidMount, componentDidUpdate ve componentWillUnmount'u değiştirir.
  • Yürütme sırası — efektler, DOM değişiklikleri commit edildikten sonra çalışır.

React'te useEffect Nedir

useEffect, React 16.8'de fonksiyonel bileşenlerde yan etkileri gerçekleştirmek için eklenmiş bir hook'tur. Yan etkiler, UI render'ı ile doğrudan ilgili olmayan işlemlerdir: API'lere HTTP istekleri, etkinlik abonelikleri, zamanlayıcılarla çalışma, DOM manipülasyonları, günlüğe kaydetme ve üçüncü taraf kütüphanelerle entegrasyon.

Hook'lardan önce, tüm bu işlemler sınıf bileşenlerinin yaşam döngüsü yöntemlerine yerleştirilmek zorundaydı: başlatma için componentDidMount, prop değişikliklerine tepki için componentDidUpdate, temizlik için componentWillUnmount. useEffect, bağımlılık dizisinin efektin ne zaman çalışması gerektiğini belirlediği tek bir API'de üç senaryoyu birleştirdi. Bu, mantığı basitleştirdi ve özellikle abonelik senaryolarında kod tekrarını azalttı.

React DevTools Usage Survey (2024)'e göre useEffect, useState'ten sonra en popüler ikinci hook'tur ve React uygulamalarının %89'unda kullanılır. Çoğu geliştirici onu veri getirme, harici sistemlerle senkronizasyon ve DOM etkinlik aboneliklerini yönetme için kullanır.

jsx
import { useEffect } from 'react';

function UserProfile({ userId }) {
    useEffect(() => {
        fetch(`/api/users/${userId}`)
            .then(res => res.json())
            .then(data => setUser(data));
    }, [userId]);
}

useEffect Nasıl Çalışır: Efekt Yaşam Döngüsü

useEffect, React render'ı tamamlayıp DOM'u güncelledikten sonra iletilen efekt işlevini çalıştırır. Bu, render zamanı hesaplamalarından önemli bir farktır: efekt render'ı engellemez, bu da UX performansı için kritiktir. Efektler senkronize olarak çalışsaydı, kullanıcılar veri yüklenirken donmuş bir arayüz görürdü.

Tipik bir efektin yaşam döngüsü üç aşamadan oluşur. Bileşen montajında React efekti çalıştırır. Her güncellemede, dizideki en az bir bağımlılık değiştiyse, React önce önceki efektin temizleme işlevini, ardından yeni efekti çalıştırır. Bileşen demonte edildiğinde, yalnızca temizleme işlevi çalışır.

React Team — useEffect RFC (2024)'e göre useEffect'in dahili uygulaması, fiber ağacında bir yan etki kuyruğu kullanır. Değişiklikleri commit ettikten sonra (commit aşaması), React bu kuyruğu dolaşır ve efekt işlevlerini bileşende bildirildikleri sırayla çağırır. Her fiber düğümü, doğru temizlik ve yeniden çalıştırma için önceki efekte bir referans saklar.

AşamaReact EylemiNe Zaman Çalışır
MontajEfekt işlevini çağırİlk render'dan sonra
Güncellemetemizlik → efektBağımlılıklar değiştiğinde
DemonteSadece temizlikBileşen kaldırıldığında

useEffect Bağımlılık Dizisi

Bağımlılık dizisi — useEffect'in ikinci argümanı — efektin ne zaman yeniden çalışması gerektiğini belirler. React, Object.is kullanarak dizideki her değeri önceki render ile karşılaştırır. En az bir değer değiştiyse, efekt yeniden çalışır. Dizi boşsa ([]), efekt montajdan sonra yalnızca bir kez çalışır.

Doğru bağımlılıkları seçmek, useEffect ile çalışmanın en zor kısmıdır. Dizi, efekt içinde kullanılan ve render'lar arasında değişebilen tüm değişkenleri ve işlevleri içermelidir. Bir bağımlılığı atlamak, eski kapanmalara (stale closures) yol açar — efekt önceki render'dan güncel olmayan bir değer görür. Gereksiz bağımlılıkları dahil etmek aşırı yeniden çalıştırmaya ve potansiyel hatalara neden olur.

jsx
// Bağımlılıklar, efektin ne zaman yeniden çalışacağını kontrol eder
useEffect(() => {
    document.title = `User: ${user.name}`;
}, [user.name]); // yalnızca user.name değiştiğinde yeniden çalıştır

// eslint-disable-next-line react-hooks/exhaustive-deps
// Bir bağımlılığı atlarsanız, güncel olmayan veri alırsınız

React, eslint-plugin-react-hooks'u exhaustive-deps kuralıyla sağlar ve bu kural, bağımlılık dizisinin eksiksizliğini otomatik olarak kontrol eder. Meta Engineering Blog (2024)'e göre bu eklentiyi etkinleştirmek, hook ile ilgili hataları %72 oranında azaltır. Özel mantık içeren nadir durumlar dışında, tüm exhaustive-deps uyarılarını bir yorumla bastırmak yerine düzeltmeniz önerilir.

useEffect Bağımlılıksız ve Boş Diziyle

Bağımlılık dizisini hiç iletmezseniz, useEffect her render'dan sonra çalışır. Bu, DOM senkronizasyonu veya günlüğe kaydetme için yararlı olabilir, ancak çoğu zaman bir hatadır: efekt çok sık çalışır ve performans kaybına yol açar. Çoğu durumda, boş bir dizi (montajda bir kez) veya belirli props/state içeren bir dizi iletmelisiniz.

Boş dizi ([]), efektin hiçbir değere bağlı olmadığı ve kesin olarak bir kez çalıştığı anlamına gelir. Bu, sınıf bileşenlerinde componentDidMount'a eşdeğerdir. Ancak şunu unutmayın: efekt, bağımlılık dizisinde listelenmeyen props veya state kullanıyorsa, efekt bunların başlangıç değerlerini kullanır ve güncellemeleri asla görmez. Buna stale capture denir ve genellikle bulunması zor hataların kaynağıdır.

Bağımlılık DizisiDavranışSınıf Eşdeğeri
Argüman yokHer render'dan sonracomponentDidUpdate
[]Montajda bir kezcomponentDidMount
[a, b]a veya b değiştiğindeComponentWillReceiveProps benzeri
return cleanupDemonte etmeyi yönetcomponentWillUnmount

useEffect'te Efektleri Temizleme

Temizleme işlevi, useEffect'in geri çağrısından döndürebileceği bir işlevdir. React, bileşen demonte edildiğinde ve bağımlılıklar değiştiğinde efekti yeniden çalıştırmadan önce onu çağırır. Temizlik, abonelikleri, zamanlayıcıları, istekleri ve serbest bırakılması gereken kaynakları iptal etmek için gereklidir.

Tipik bir örnek, WebSocket aboneliğidir. Montajda bir bağlantı oluşturulur; bağımlılık güncellemesinde yeniden oluşturulur (temizlik eskisini kapatır, efekt yenisini açar); demonte edildiğinde kapatılır. Temizlik olmadan, bileşenin her yeniden montajı yeni bir WebSocket bağlantısı oluşturur ve bu da bellek sızıntılarına ve birden çok bağlantıya yol açar.

jsx
useEffect(() => {
    const socket = new WebSocket('wss://api.example.com');
    socket.onmessage = event => setData(event.data);

    // Temizleme işlevi — demonte etme sırasında ve yeniden çalıştırmadan önce çalışır
    return () => {
        socket.close();
    };
}, []);

React Documentation (2025)'e göre AbortController, temizlikte fetch isteklerini iptal etmek için modern yaklaşımdır. Efekt bir HTTP isteği yaparsa ve bileşen tamamlanmadan demonte edilirse, istek çalışmaya devam eder ve demonte sonrası setState bir hataya neden olur. Efektin içinde bir AbortController oluşturun ve isteği iptal etmek için temizlikte controller.abort()'u çağırın.

useEffect ile Sık Yapılan Hatalar

En yaygın hata bağımlılıkları atlamaktır. Örneğin, efekt userId prop'unu kullanır, ancak bağımlılık dizisi boştur. Sonuç olarak, efekt ilk userId değeriyle bir kez çalışır ve değişikliklerine asla tepki vermez. Geliştirici, bileşenin yeni bir userId aldığını görür ancak veriler güncellenmez. exhaustive-deps kuralına sahip eslint-plugin-react-hooks bu tür hataları otomatik olarak algılar.

  • Sonsuz döngü — efekt içinde state'i güncellemek, efekti tekrar çalıştıran bir yeniden render'a neden olur. Çözüm: bağımlılık dizisini kontrol edin veya setter'ın işlevsel formunu kullanın.
  • Yarış durumu (race condition) — userId hızla değişirse, ilk userId için istek ikinciden sonra tamamlanabilir ve yanlış veri gösterebilir. Çözüm: iptal edilmiş bayrağı veya AbortController kullanın.
  • Gereksiz efektler — ilgisiz mantığı tek bir useEffect'te birleştirmek. React, aynı bağımlılık dizisini paylaşsalar bile mantığı birden çok efekte bölmeyi önerir.
  • Unutulan temizlik — etkinliklerden abonelikten çıkmamak, zamanlayıcıları temizlememek veya istekleri iptal etmemek, bellek sızıntılarına ve demonte sonrası setState hatalarına yol açar.
jsx
// ❌ Race condition — iptal yok
useEffect(() => {
    fetch(`/api/user/${userId}`).then(res => setUser(res));
}, [userId]);

// ✅ AbortController ile düzeltildi
useEffect(() => {
    const controller = new AbortController();
    fetch(`/api/user/${userId}`, { signal: controller.signal })
        .then(res => setUser(res));
    return () => controller.abort();
}, [userId]);

Sonsuz döngü sorununu çözmek için, önceki state'e dayalı olarak state'i güncelleyen mantığı useEffect'e koymaktan kaçının. setState'in işlevsel formunu kullanın veya hesaplamaları efekt dışına taşıyın. Efekt, depolama veya tarayıcı etkinliklerine abone oluyorsa, dinleyici örneğinin her render'da değil, bir kez oluşturulduğundan emin olun.

Sıkça Sorulan Sorular

useEffect içinde async/await kullanabilir miyim?

Doğrudan — hayır, çünkü useEffect senkron bir işlev veya undefined döndürülmesini bekler. Geri çağrı async olarak bildirilirse, React'in yok saydığı bir Promise döndürür ve temizleme mekanizması çalışmayı durdurur. Çözüm: efekt içinde bir async işlevi çağırın: useEffect(() => { async function load() { ... }; load(); }, []).

Bir bileşende kaç tane useEffect olabilir?

Sınır yoktur. React, aynı bağımlılık dizisine sahip olsalar bile ilgisiz mantığı ayrı useEffect'lere ayırmayı önerir. Her efekt, açıkça tanımlanmış bir yan görevden sorumlu olmalıdır: biri abonelikler için, diğeri veri yükleme için, üçüncüsü sekme başlığını senkronize etme için. Bu, anlamayı ve hata ayıklamayı basitleştirir.

StrictMode'da useEffect neden iki kez çalışır?

React Strict Mode'da (yalnızca geliştirme modu), tüm efektler monte edilir, demonte edilir ve yeniden monte edilir. Bu bir özelliktir, hata değildir — React, temizliğin doğru çalışıp çalışmadığını kontrol eder. Demonte etme ve yeniden monte etmeden sonra efekt yanlış davranırsa (örneğin, yinelenen abonelikler), temizliğiniz eksiktir. Üretimde efekt bir kez çalışır.

useEffect'te bir fetch isteği nasıl iptal edilir?

AbortController kullanın. Efektin içinde bir controller oluşturun, controller.signal'ı fetch'e iletin ve temizlikte controller.abort()'u çağırın. İstek tamamlanmadan bileşen demonte edilirse, fetch iptal edilir ve setState çağrılmaz. Bu, yarış durumlarını ve “Can't perform a React state update on an unmounted component” hatasını önler.

Bağımlılık dizisini iletmezsem ne olur?

useEffect istisnasız her render'dan sonra çalışır. Bu, efekt içindeki herhangi bir setState'in yeni bir render → yeni efekt → sonsuz döngüye neden olacağı anlamına gelir. Pratikte, bağımlılık dizisi olmayan bir efekt neredeyse her zaman bir hatadır. İstisnalar, her render'ın senkronizasyon gerektirdiği günlüğe kaydetme veya harici bir sistemle senkronizasyondur.

Özet

  • useEffect, DOM commit'inden sonra yan etkileri gerçekleştirmek için bir hook'tur, componentDidMount, componentDidUpdate ve componentWillUnmount'u değiştirir.
  • Bağımlılık dizisi, efektin yeniden çalışmasını kontrol eder; boş dizi = bir kez, bağımlılıkları atlama = eski kapanma.
  • Temizlik abonelikler, zamanlayıcılar ve istekler için zorunludur; aksi halde bellek sızıntıları oluşur.
  • AbortController, yarış durumlarını önleyerek useEffect içinde fetch isteklerini iptal etmenin doğru yoludur.
  • StrictMode, temizliğin doğruluğunu doğrulamak için geliştirme modunda efekti iki kez monte eder.
  • Efektleri ayırın — her useEffect, bağımlılıklar eşleşse bile bir görevi işler.
  • eslint-plugin-react-hooks bağımlılık dizisinin eksiksizliğini otomatik olarak kontrol eder ve hataları %72 azaltır.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun