Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

React'te state update'leri batch'leme mekanizmasını anlamadan yaşadığım beklenmedik davranış ve çözümü

stackor

Üye
Katılım
14 Mart 2026
Mesajlar
33
Merhaba arkadaşlar, bugün başımı çok ağrıtan bir React sorununu ve nasıl çözdüğümü anlatacağım. Olay, bir bileşen içinde ard arda yaptığım state güncellemelerinin, benim beklediğim sırada ve sayıda render'a sebep olmamasıydı. "Bu state'i 3 kere güncelliyorum, neden 3 kere render olmuyor?" diye kafayı yemiştim. Meğer React'in güzel bir optimizasyonu varmış: state update batching.

🔥 Karşılaştığım Sorun

Basit bir sayaç ve loglama bileşeni yazıyordum. Kullanıcı bir butona tıkladığında, sayaç state'i artacak, aynı anda bir log listesine bu artışın bilgisi eklenecekti. Kodum şöyleydi:

JavaScript:
function Counter() {
  const [count, setCount] = useState(0);
  const [logs, setLogs] = useState([]);

  const handleClick = () => {
    // 1. Sayaç artırılıyor
    setCount(count + 1);
    // 2. Log listesine yeni kayıt ekleniyor
    setLogs([...logs, `Count updated to: ${count + 1}`]);

    console.log('Current count in function:', count);
  };

  console.log('Component rendered. Count:', count);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={handleClick}>Increment</button>
      <ul>
        {logs.map((log, i) => <li key={i}>{log}</li>)}
      </ul>
    </div>
  );
}

Butona ilk tıkladığımda konsolda "Component rendered. Count: 1" gördüm. Süper. Ama log listesine baktığımda "Count updated to: 1" yazmasını beklerken, "Count updated to: 0" yazdığını gördüm! İşte o an küçük bir kriz yaşadım. `setCount` ve `setLogs` arka arkaya çağrılıyordu, `count` değeri bir artmış olmalıydı. Neden log eski değeri yakaladı?

⚙️ Batch'leme (Toplu İşleme) Nedir?

Araştırmaya başladığımda React'in bir performans optimizasyonu yaptığını öğrendim. React, bir olay işleyicisi (event handler) içinde yapılan tüm senkron state güncellemelerini "topluyor" (batch'liyor). Yani `handleClick` fonksiyonu tamamlanana kadar, `setCount` ve `setLogs` çağrıları hemen render tetiklemiyor. React bunları bir araya getirip tek bir render işleminde gerçekleştiriyor.

Bu harika bir şey, çünkü gereksiz render'ları önlüyor. Ancak sorun şu: Bu toplu işlem sırasında, tüm state setter fonksiyonları, o anki render'da geçerli olan (yani henüz güncellenmemiş) `count` değerini görüyor. Bu yüzden `setLogs([...logs, `Count updated to: ${count + 1}`])` satırındaki `count` hala 0!

💡 Çözüm: Functional Update ve useEffect

Çözüm için iki ana yöntem var. İşte benim kullandığım en temiz çözümler:

1. Yöntem: Functional (Updater) State Update
`setState` fonksiyonuna sadece yeni değer değil, bir fonksiyon da verebiliriz. Bu fonksiyon, bir önceki state değerini parametre alır ve yeni state'i döndürür. Bu sayede her zaman en güncel state değerine ulaşırız.

JavaScript:
const handleClick = () => {
  // Functional update kullanarak count'u güncelle
  setCount(prevCount => prevCount + 1);
  // Yeni log eklerken, functional update ile bir önceki count değerini kullan
  setLogs(prevLogs => [...prevLogs, `Count updated to: ${prevLogs.length + 1}`]); // Veya count yerine başka bir mantık
};

Ama burada dikkat! Loga yazmak için `prevCount`'a ihtiyacım var, ancak `setLogs`'un updater fonksiyonu sadece `prevLogs`'u alıyor. Bu durumda ikinci yöntem daha uygun.

2. Yöntem: useEffect ile Tepki Vermek[/COLOR]
Aslında yapmak istediğim şey, `count` state'i her değiştiğinde `logs` state'ini güncellemek. Bu bir yan etki (side effect). Yan etkileri işlemek için `useEffect` hook'u var.

JavaScript:
function Counter() {
  const [count, setCount] = useState(0);
  const [logs, setLogs] = useState([]);

  // Count değiştiğinde çalışacak yan etki
  useEffect(() => {
    // Log listesini güncelle
    setLogs(prevLogs => [...prevLogs, `Count updated to: ${count}`]);
  }, [count]); // Bağımlılık dizisi: count değiştiğinde tetiklenir.

  const handleClick = () => {
    setCount(count + 1); // Sadece count'u güncelle
  };

  // ... Geri kalan JSX
}

İşte bu! Artık `count` ne zaman güncellense, `useEffect` otomatik olarak çalışıp log listesini en güncel `count` değeri ile güncelliyor. Kod daha temiz ve davranışı tahmin edilebilir oldu.

🎯 Sonuç ve Özet

React'in otomatik batch'leme özelliği, performans için harika ama state güncellemelerinin birbirine bağlı olduğu durumlarda kafa karıştırıcı olabiliyor. Bu durumda:
1. Bir state diğerinin anlık değerine bağlıysa, functional update kullan.
2. Bir state diğerinin değişmesine tepki vermesi gerekiyorsa (yan etki), useEffect kullan.

Siz React'te benzer bir "batch'leme tuzağına" düştünüz mü? Veya state senkronizasyonu için farklı, daha şık bir pattern kullanıyor musunuz? Yorumlarda paylaşalım!
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri