Programlama

React Hooks’u Anlamak: Kuralların Arkasındaki Gerçek

Geçen ay, Kadıköy’de bir kahve molasında bir geliştirici arkadaşım bana aynı soruyu fırlattı: “Tamam da hooks niye böyle çalışıyor?” Açık konuşayım — o an masada herkesin yüzünde aynı ifade vardı (kendi tecrübem) (bu beni çok şaşırttı). Kuralı biliyoruz. Hatta ezbere biliyoruz. Ama işin aslı şu ki, çoğu React geliştiricisi hook’ları her gün kullanıyor; nasıl yürüdüğünü ise pek kurcalamıyor. Bir bakıma, neden? Çünkü çalışıyor işte.

Açıkçası, Ben de yıllarca öyleydim. 2023 yazında, İstanbul’da küçük bir SaaS projesinde state karmaşasıyla boğuşurken bunu net gördüm: kod çalışıyordu ama zihinsel modelim eksikti, hatta çürüktü. Hook kuralları sanki “büyücü sözü” gibiydi — — en azından ben öyle düşünüyorum — yapıyorsun, oluyor, neden olduğunu sorgulamıyorsun. Sonra bir gün o model çatlıyor ve bütün sistemin ipleri elinizde dağılıyor.

💡 Bilgi: Hook kuralları aslında keyfi değil; React’in state’i sırayla takip etmesi için gerekli. Yani mesele “yasaklar” değil, veri yapısının kendisi.

Neden Herkes Hook Kullanıyor Ama Az Kişi Açıklayabiliyor?

Bak şimdi… React dünyasında hook’lar günlük ekmek gibi oldu. useState, useEffect, useMemo, useRef — liste uzayıp gidiyor. Fakat bu kadar yaygın kullanılan bir şeyin iç mantığına gelince ortam biraz sessizleşiyor. Neden? Çünkü dokümantasyon sana çoğunlukla “ne yapacağını” söylüyor; “neden böyle yapmak zorunda olduğunu” değil. İkisi çok farklı şeyler.

Evet, doğru duydunuz. Daha fazla bilgi için Korku Filminde Jump Scare Öncesi Uyarı: Binge Nedir? yazımıza bakabilirsiniz.

Bence buradaki en büyük hayal kırıklığı da bu zaten. Hele bir de genç ekiplerde şunu tekrar tekrar gördüm: biri useEffect ile işi çözüyor, dependency array patladığında ise konu büyülü sis bulutuna dönüşüyor. Halbuki problem efektte değil — state ve render akışını kafada doğru oturtamamakta yatıyor.

Bir de şu var. ESLint kuralı gelip seni kırmızıyla uyarınca insan ister istemez “tamam tamam” deyip geçiyor. Pratikte iş görüyor, itirazım yok. Ama denetleyici olmak başka şey, açıklayıcı olmak bambaşka şey.

Tek Bir Değişkenle Başlayan Yanılgı

İlk bakışta basit bir useState implementasyonu yazmak çok cazip geliyor. Tek değişken koyarsın, değeri saklarsın, setState ile güncellersin; mis gibi görünür. Nitekim ben bunu ilk kez 2019’da Ankara’daki bir frontend atölyesinde anlatırken herkes başını sallıyordu — örnek temizdi, anlaşılırdı, mantıklıydı.

let state;
function useState(initialValue) {
state = state ? initialValue;
function setState(newValue) {
state = newValue;
rerender();
}
return [state, setState];
}

Evet. Tek komponentli minicik senaryoda bu yaklaşım çalışır gibi görünür. Counter’a tıklarsın, sayı artar. Tamam. Ama ikinci bileşeni eklediğin anda ortalık karışır, çünkü tek global değişken herkese yetmeye çalışır — ve yetmez.

Küçük startup projelerinde bu tip kısa yol çözümlerini ara sıra görüyorum; hızlı teslim baskısı altında kimse alt mimariyi düşünmüyor, insanlık hali. Fakat enterprise tarafta böyle bir yapı iki sprint içinde duvara toslardı. Mesele sadece kod yazmak değil yani — kodun hafızasını doğru kurgulamak.

Peki sorun tam olarak ne?

Sorun şu: React aynı anda birçok component render edebiliyor ve her biri kendi geçmişini, kendi hafızasını taşımalı. Tek global değişken varsa herkes aynı deftere not düşer gibi oluyor — kaos çıkar tabii. Başka türlüsü mümkün değil.

Peki neden?

Yaklaşım Küçük proje Büyük proje Sorun
Tek global state Kısa vadede iş görür Kopar gider Tüm component’ler birbirine girer
Dizi tabanlı hook sistemi Bayağı yeterli Daha ölçeklenebilir Sıralama korunmazsa bozulur
Ağaç/instance tabanlı yapı Daha karmaşık gelir Sağlam durur Maliyet artar ama düzen kazanılır

Asıl Numara: Sıra Takibi İçin Dizi Yapısı

Biraz tuhaf başlık attım ama kasıtlı yaptım — çünkü hook’ların kalbi tam burada atıyor. React’in sırrı aslında sihirli olmaması. Sadece her render’da hook çağrılarını aynı sırada eşleştirmesi gerekiyor. Bu kadar.

Bunu en sade haliyle şöyle düşün: evde çekmecelerin var ve her çekmece belli bir şeyi tutuyor. İlk çekmece count. İkinci çekmece loading. Üçüncü çekmece user. Sırayı bozarsan çorap ararken faturayı bulursun — tam olarak bu.

Hook’ların “top level” kuralı keyfi değildir; çağrı sırası bozulursa React yanlış veriyi yanlış hook’a bağlar.

İşte bu yüzden koşulların içine hook koyamazsın. If bloğunun içinde çağırırsan sıra kayar. Loop içinde dersen yine kayar. Nested function’a sokarsan işler daha da çorba olur. Çünkü ikinci render’da hangi satırda hangi state’in durduğunu artık bilemezsin.

Neden koşullar yasak?

Diyelim ilk render’da if bloğu çalışmadı ve o hook atlandı. İkinci render’da blok çalıştıysa listeye yeni bir eleman girmiş olur. Sonraki pek çok kayıtlar kayar. Böyle olunca React “count” sandığın yeri “user” diye okumaya başlayabilir. Güzel olmaz. Hiç de güzel olmaz.

Evet, doğru duydunuz.

Kullanıcı Tarafında Görülen Şey ile İçerde Olan Şey Aynı Değil

Şunu söyleyeyim, Dışarıdan bakınca biz sadece fonksiyon component’i görüyoruz. Ama içeride olan şey daha mekanik: render baştan sona tekrar ediyor ve her seferinde hooks listesi yeniden okunuyor. Bu yüzden function component’ler saf görünmeli — yani girdiye göre çıktı veren minik makineler gibi davranmalı. Yan etkiler kontrollü yerde olmalı.

Bu noktada geçen yıl Berlin’de katıldığım mini konferansı hatırladım. Orada biri “React devlet memuru gibi davranıyor” demişti. Aslında kötü bir benzetme sayılmaz — evrak sırası bozulmasın istiyor. Sen de formu yanlış kutuya doldurmayacaksın işte.

useEffect neden kafa karıştırıyor?

Bir şey dikkatimi çekti: Bana kalırsa en çok can sıkan hook hala useEffect. Çünkü insanlar onu lifecycle yerine geçiriyor ya da veri akışı yerine küçük büyü kutusu sanıyor. Dependency array de işte bunun yan ürünü.

Bakın, Bir e-ticaret dashboard projesinde, İzmir’de çalışan ekipten biri bana “array’e ne koyacağımı nasıl anlayacağım?” diye sormuştu. Cevabım sert geldi belki: “Efekt neye bağlıysa onu koy.” Ama sonra oturdum düşündüm — mesele yalnızca bağımlılık listesi değil. Efektin gerçekten side effect olup olmadığını anlamak gerekiyor. Eğer hesaplama yapıyorsan useMemo daha uygun olabilir; DOM dışına çıkıyorsan useEffect mantıklı. İnce çizgi ama önemli. Bu konuyla ilgili Yapay Zeka Destekli Google Finans Türkiye’de: Ne Değişti? yazımıza da göz atmanızı tavsiye ederim. Bu konuyla ilgili Apple-Samsung Veri Savaşı: Antitröstte Yeni Perde yazımıza da göz atmanızı tavsiye ederim.

Kendi Kendine Yetmeyen Kurallar Yerine Fizik Gibi Çalışan Sistem

Hook kuralları dışarıdan yasa gibi görünür. Ama iç tasarım anlaşıldığında fizik yasasına dönüşür. Mesela yerçekimi için “düşmemek yasaktır” demiyoruz; düşüş doğal sonuçtur. Hook’larda da olay aynı: sıra korunmuyorsa sistem dağılıyor. Bu kadar basit. Ve evet, biraz acımasız.

  1. Sabit sıra: Her render’da hooks aynı sırada çağrılır. — bunu es geçmeyin
  2. Ayrılmış hafıza: Her component kendi slot’larına sahip.
  3. Tahmin edilebilirlik: React hangi verinin nereye ait olduğunu bilir.
  4. Linter desteği: İnsan unutursa araç hatırlatır. — bunu es geçmeyin

Vallahi, Güzel taraf şu: öğrenmesi ilk etapta kolay, ustalaşması ise şaşırtıcı derecede derin. Kötü taraf mı? Başlangıçta soyut kalabiliyor. Hele junior geliştiriciler için “kurala uy” cevabı pek tatmin etmiyor — biraz pişmesi lazım yani.

Pratikte Ne Anlama Geliyor?

Küçük ekiplerde hooks’u doğru anlamak size temiz refactor alanı açıyor. Mesela feature flag’lerle bazı ekranları açıp kapatırken conditional logic’i bile daha sakin yazıyorsunuz. Enterprise projelerdeyse kazanç başka yerde: testler stabil kalıyor, bug sayısı azalıyor, code review sırasında tartışmalar yarıya iniyor. Somut fark. Java’da Method Nedir? Kısa Kodla Büyük İşler yazımızda da bu konuya değinmiştik. Java’da Method Overloading: Aynı İsim, Farklı İş yazımızda da bu konuya değinmiştik.

Ama dürüst olayım. Her şeyi çözen sihir yok. Bazı takımlar hooks’a fazla yük bindirip business logic’i component içine gömuyor — dosya büyüyor, okunurluk düşüyor, iş çığırından çıkıyor. Beklediğim kadar iyi olmayan örneklerin çoğu oradan çıkıyor zaten. Araç iyi; kullanım şekli bazen berbat.

Eğer isterseniz bunu JavaScript’teki event loop mantığıyla kıyaslayabilirsiniz. Nasıl ki async akışını bilmeden promise zinciri elinizde patlayabiliyorsa, hooks’un iç düzenini bilmeden de dependency array sizi sinir eder. Sistem gözle görülmez ama etkisi gündelik kodda çok hissedilir.

💡 Bilgi: Kafanda şu cümleyi tut: “Hooks = sıralı slot sistemi + yeniden render + stabil çağrı düzeni.” Bunu anlarsan geri kalan ayrıntılar yerlerine oturmaya başlıyor.

Sana Hemen İşe Yarayan Bir Bakış Açısı

Bir sonraki projende şunu dene. Hook kullanırken kendine üç soru sor: Bu değer nerede saklanacak? Ne zaman güncellenecek? Render tekrarlandığında sıra bozulacak mı? Bu üç soru genelde konuyu toparlıyor — inanılmaz derecede basit. Etkili.

Hani, Geçen hafta Levent’teki ofiste bunu bir arkadaşa anlattığımda “aa mesele buymuş” dedi. Evet, mesele çoğu zaman gerçekten bu kadar çıplak. Ama önce kabuğunu soyman gerekiyor.

Hook’lar mistik değil — sadece iyi tasarlanmış, sıra temelli bir kayıt sistemi. Bunu kavradığında useState de, useEffect de, custom hook’lar da daha az gizemli görünüyor. Ve açıkçası, kod yazmak biraz rahatlıyor.

Sıkça Sorulan Sorular

React Hook nedir?

Hook’lar, function component içinde state ve yan etkileri yönetmek için kullanılan özel API’lerdir..
En çok bilinenleri useState ve useEffect’tir..
Kısacası class component’e ihtiyaç duymadan modern React akışı sağlarlar..

Hook’lar neden sadece üst seviyede çağrılmalı?

Çünkü React hook’ları sırayla okur..
Koşul veya döngü içinde çağrı yaparsanız sıra değişir ve yanlış state’e bağlanabilirsiniz..
Kuralın amacı tam olarak budur..

useEffect neden sık hata verir?

Çoğu hata dependency array’in yanlış kurulmasından çıkar..
Efektin hangi verilere bağlı olduğunu doğru belirtmezseniz gereksiz tetiklenmeler veya eksik güncellemeler yaşarsınız..
Sorunun kökü genelde mekanikten ziyade modelleme tarafındadır..

Custom hook ile normal fonksiyon arasındaki fark nedir?

Custom hook diğer hooks’u kullanabilen özel bir fonksiyondur..
Normal JavaScript fonksiyonlarında ise doğrudan React hooks çağırmanız beklenmez..
Yani custom hook,
yeniden kullanılabilir UI mantığı paketlemek için vardır..

React Rules of Hooks Dokümantasyonu

eslint-plugin-react-hooks GitHub Deposu

React Learn — State as a Component’s Memory

Aşkın KILIÇ

20+ yıl deneyimli Azure Solutions Architect. Microsoft sertifikalı bulut mimari ve DevOps danışmanı. Azure, yapay zekâ ve bulut teknolojileri üzerine Türkçe teknik içerikler üretiyor.

AZ-305AZ-104AZ-500AZ-400DP-203AI-102

Bu içerik işinize yaradı mı?

Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.

Haftalık Bülten

Her pazar özenle seçilmiş teknoloji yazıları doğrudan e-postanıza gelsin.

← Onceki Yazi
Google’ın Canlı Çevirisi Telefona Geliyor: İngilizce Bariyeri Sarsılıyor
Sonraki Yazi →
Java'da Method Overloading: Aynı İsim, Farklı İş

Yorum Yaz

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Haftalık Bülten

Azure, DevOps ve Yapay Zeka dünyasındaki en güncel içerikleri her hafta doğrudan e-postanıza alın.

Spam yok. İstediğiniz zaman iptal edebilirsiniz.
📱
Uygulamayı Yükle Ana ekrana ekle, çevrimdışı oku
Kategoriler
Ara
Paylaş
İçindekiler
← Google’ın Canlı Çevirisi Telef...
Java’da Method Overloadi... →
📩

Gitmeden önce!

Her pazar özenle seçilmiş teknoloji yazıları ve AI haberleri doğrudan e-postanıza gelsin. Ücretsiz, spam yok.

🔒 Bilgileriniz güvende. İstediğiniz zaman ayrılabilirsiniz.

📬 Haftalık bülten: Teknoloji + AI haberleri