Mehmet

WFN Üye
Konular
1,851
Mesajlar
1,852
Çözüm
0
Ticaret Puanı
0
Üyelik
1 Ay 6 Gün
Konum
YurtDışı
Web Sitesi
Var
Alanı
Google Adsense
1/1
Konu sahibi
React useEffect, bileşenin render sonucu DOM'a uygulandıktan sonra çalışır. İlk render sonrasında bir kez, bağımlılık dizisindeki değerler değiştiğinde yeniden veya bağımlılık dizisi verilmezse her başarılı render sonrasında çalışabilir. Bu nedenle veri çekme, abonelik kurma, document başlığını değiştirme ve React dışındaki bir API ile senkronizasyon gibi yan etkiler için kullanılır; render sırasında çalışması gereken hesaplamalar için kullanılmaz.

Çalışma sırası​


Bir bileşen güncellendiğinde genel akış şöyledir:

  1. React bileşeni çalıştırır ve yeni JSX'i hesaplar.
  2. React değişiklikleri DOM'a uygular; buna commit aşaması denir.
  3. Effect'in bağımlılıkları kontrol edilir.
  4. Bağımlılık değiştiyse önce eski effect’in cleanup işlevi eski değerlerle çalışır. İlk kurulumda eski cleanup yoktur.
  5. Ardından yeni effect’in setup callback’i yeni değerlerle çalışır; unmount sırasında son cleanup çağrılır.

Effect'in tam olarak tarayıcının boyamasından önce veya sonra çalışacağına güvenilmemelidir. Kullanıcıya görünmeden önce layout ölçümü gibi bir iş yapılması gerekiyorsa useLayoutEffect ayrı bir kullanım alanıdır. Normal yan etkilerde useEffect tercih edilir.

Bağımlılık dizisine göre davranış​


Aşağıdaki ayrım, effect'in ne zaman yeniden çalışacağını belirler:

KodNe zaman çalışır?Tipik kullanım
useEffect(fn)Her commit sonrasındaNadiren gerekir; her çalışmada yan etkiyi bilinçli yönetmek gerekir
useEffect(fn, [id])İlk commit'ten sonra ve id değişinceSeçili kaydı veya URL parametresini izlemek
useEffect(fn, [])Bileşen ilk kez commit edildikten sonra; cleanup unmount sırasındaBileşenin yaşam döngüsüne bağlı kurulumlar

React her bağımlılığı önceki değerle Object.is kullanarak karşılaştırır; derin içerik karşılaştırması yapmaz. Dizideki bir nesne, dizi veya fonksiyon her render'da yeniden oluşturuluyorsa içerik aynı görünse bile referansı değişebilir ve effect yeniden çalışabilir. Bu yüzden bağımlılık dizisini eksik yazarak yeniden çalışmayı gizlemek yerine, effect'in kullandığı değerleri doğru biçimde belirtmek gerekir.

Somut örnek: id değişince veri çekmek​


Aşağıdaki örnekte effect ilk render sonrasında çalışır; userId değişirse önceki isteğin sonucu artık geçersiz olabileceği için cleanup ile işlem iptal edilir. fetch başarısız olursa hata durumu gösterilir.

JavaScript:
import { useEffect, useState } from "react";

export default function UserCard({ userId }) {
  const [user, setUser] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const controller = new AbortController();
    let active = true;

    setUser(null);
    setError(null);

    fetch(`https://api.example.com/users/${encodeURIComponent(userId)}`, {
      signal: controller.signal
    })
      .then((response) => {
        if (!response.ok) throw new Error("İstek başarısız");
        return response.json();
      })
      .then((data) => { if (active) setUser(data); })
      .catch((reason) => {
        if (active && reason.name !== "AbortError") setError(reason);
      });

    return () => {
      active = false;
      controller.abort();
    };
  }, [userId]);

  if (error) return <p>Veri alınamadı.</p>;
  if (!user) return <p>Yükleniyor...</p>;
  return <p>{user.name}</p>;
}

Bu bileşen başarıyla çalıştığında önce Yükleniyor..., istek tamamlanırsa kullanıcının adı görünür. userId değiştiğinde eski istek için iptal istenir ve yeni istek başlatılır. active kontrolü, eski async işin geç gelen sonucunun state’e yazılmasını da engeller; tarayıcının iptal etmesi sunucudaki işi mutlaka durdurmaz. api.example.com yalnızca örnek alan adıdır; gerçek uygulamada kendi API adresinizi kullanmanız gerekir.

Uygularken kontrol listesi​


  1. Effect'in gerçekten React dışındaki bir sistemle senkronizasyon yapıp yapmadığını kontrol edin. Yalnızca bir değeri başka bir değerden hesaplıyorsanız bunu render içinde veya useMemo ile hesaplamak daha uygundur.
  2. Effect callback'inin kullandığı props, state ve fonksiyonları bağımlılık dizisine ekleyin.
  3. Abonelik, zamanlayıcı, olay dinleyicisi veya devam eden istek başlatıyorsanız cleanup döndürün.
  4. Effect'in beklenenden fazla çalıştığını görürseniz bağımlılıkların referanslarının her render'da değişip değişmediğini inceleyin.
  5. Geliştirme ortamında aynı kurulum ve cleanup akışını art arda görürseniz Strict Mode davranışını dikkate alın. Cleanup kodu doğruysa üretim davranışını yanlış yorumlamazsınız.

Effect yalnızca istemci tarafında çalışır; sunucu tarafı render sırasında tarayıcıya özgü DOM veya ağ yan etkilerine güvenilmemelidir. Ayrıca effect'in içinden state değiştirmek yeni bir render başlatabileceğinden, bağımlılıkları değişen state'i yeniden yazan bir effect sonsuz döngü oluşturabilir.

Kaynaklar​



Sık sorulan sorular​


useEffect içindeki async fonksiyonu doğrudan callback olarak yazabilir miyim?​

Hayır. Effect callback'inin doğrudan bir Promise döndürmesi cleanup sözleşmesiyle çakışabilir. Bunun yerine effect içinde async bir fonksiyon tanımlayıp çağırın ve cleanup işlemini effect callback'inden döndürün.

useEffect neden bazen iki kez çalışıyor gibi görünür?​

Geliştirme ortamındaki Strict Mode, cleanup kodunun güvenilirliğini denetlemek için kurulum ve temizleme akışını tekrar tetikleyebilir. Yan etkiyi tek seferlik varsaymak yerine cleanup ile güvenli hâle getirin.

Her render'da çalışan effect nasıl durdurulur?​

İhtiyacınız olan değerleri bağımlılık dizisinde açıkça belirtin. Effect aslında gerekli değilse onu kaldırıp hesabı render sırasında yapın; boş dizi eklemek yalnızca yeniden çalışmayı bastırmak için kullanılmamalıdır.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Konuyu görüntüleyenler

Bu konuyu şu anda görüntüleyen üye bulunmuyor.