React'in Bileşenlerle Frontend Mimarisi Üzerindeki Etkisi
React, bileşen tabanlı UI'ı, deklaratif render'ı ve durum odaklı görünümleri popülerleştirerek ekipleri sayfa-merkezli koddans yeniden kullanılabilir sistemler ve kalıplara taşıdı.

React Ortaya Çıkınca Neler Değişti
React yalnızca yeni bir kütüphane tanıtmadı—ekiplerin “frontend mimarisi” derken ne kastettiğini değiştirdi. Pratikte frontend mimari, bir UI kod tabanını ölçekle anlaşılır kılan kararlar bütünüdür: UI'yı nasıl parçalara ayırdığınız, verinin bu parçalar arasında nasıl aktığı, durumun nerede tutulduğu, yan etkileri (örn. veri çekme) nasıl ele aldığınız ve sonucu ekibin içinde nasıl test edilebilir ve tutarlı tuttuğunuz.
Bir cümlede bileşen düşüncesi
Bileşen düşüncesi, UI'nın her parçasını kendi render'ından sorumlu, küçük ve tekrar kullanılabilir bir birim olarak ele almak ve bu birimleri diğerleriyle bileştirerek tam sayfalar oluşturabilmektir.
React’in teşvik ettiği değişimler
React popüler olmadan önce birçok proje sayfalar ve DOM manipulasyonu etrafında organize olurdu: “şu elementi bul, metnini değiştir, bu sınıfı aç/kapat.” React ekipleri farklı bir varsayıma itti:
- Durum odaklı UI: durumu güncellersiniz, UI buna göre güncellenir.
- Bağlam yerine kompozisyon: ekranları birbirine alakasız dosyalar üzerinden davranış bağlayarak değil, bileşenleri iç içe geçirip birleştirerek inşa edersiniz.
- Tekrar kullanım birincil hedef: paylaşılan UI kalıpları kopyalanmış markup değil, bileşen olur.
Bu fikirler günlük işi değiştirdi. Kod incelemeleri artık “bu durum nereye ait?” diye sorar oldu, seçici kullanımı sorusu yerine sahiplik soruluyor; tasarımcılar ve mühendisler ortak bir bileşen sözlüğünde hizalanabildi ve ekipler tüm sayfaları yeniden yazmadan UI yapı taşları kütüphaneleri büyütebildi.
React'ten daha büyük
Bir ekip daha sonra başka bir çerçeveye geçse bile, React'in şekillendirdiği alışkanlıklar çoğunlukla kalır: bileşen-tabanlı mimari, deklaratif render, öngörülebilir veri akışı ve tek seferlik sayfa kodu yerine yeniden kullanılabilir tasarım sistemi bileşenlerine eğilim. React bu kalıpları normalleştirdi ve bu da daha geniş frontend ekosistemini etkiledi.
React Öncesi: Sayfa-Merkezli UI'lar ve DOM-Öncelikli Kod
React'ten önce birçok ekip arayüzleri sayfalar etrafında, yeniden kullanılabilir UI birimleri yerine inşa ediyordu. Yaygın bir yapı sunucu tarafı render edilmiş şablonlardı (PHP, Rails, Django, JSP vb.) ve üstüne interaktivite için jQuery serpilirdi.
Tipik yığın: şablonlar + jQuery + eklentiler
Bir sayfa render edilir, sonra scriptlerle “aktive” edilirdi: tarih seçiciler, modal eklentileri, form doğrulayıcılar, karuseller—her birinin kendi markup beklentileri ve olay kancaları vardı.
Kod genellikle şöyle görünürdü: bir DOM düğümü bulun, bir handler bağla, DOM'u değiştir, ve umarım başka bir şey bozulmaz. UI büyüdükçe “gerçek kaynak” usulca DOM'un kendisi haline geliyordu.
Davranış katmanlara dağılmıştır
UI davranışı nadiren tek bir yerde yaşardı. Şöyle bölünürdü:
- Sunucu görünümleri (koşullu render, partial'lar, feature flag'ler)
- HTML (data-* öznitelikleri, inline handler'lar, gizli alanlar)
- JavaScript (jQuery seçicileri, global durum, eklenti başlatma)
Tek bir widget—örneğin bir ödeme özeti—kısmen sunucuda oluşturulmuş, kısmen AJAX ile güncellenmiş ve kısmen bir eklentiyle kontrol ediliyor olabilir.
Yaygın sıkıntılar
Bu yaklaşım küçük iyileştirmeler için işe yarasa da tekrar eden sorunlar üretiyordu:
- Tekrarlanan UI: aynı “bileşen” birden fazla şablon ve sayfada yeniden oluşturuluyor
- Tutarsız durum: yükleme göstergeleri, devre dışı bırakılmış butonlar ve hata mesajları uyumsuz hale geliyor
- Kırılgan DOM kodu: küçük markup değişiklikleri seçicileri ve olay bağlamayı bozuyor
Erken MV* köprü olarak
Backbone, AngularJS ve Ember gibi framework'ler modeller, görünümler ve yönlendirme ile yapıyı getirmeyi denediler—çoğu zaman büyük bir iyileşme. Ancak birçok ekip yine de kalıpları karıştırdı ve tekrar edilebilir birimlerle UI kurmanın daha basit bir yoluna ihtiyaç vardı.
Büyük Fikir: UI, Durumun Bir Fonksiyonudur
React'in en önemli kayması söylemesi basit ama uygulamada şaşırtıcı derecede güçlüdür: UI, durumun bir fonksiyonudur. DOM'u “gerçek kaynak” olarak görüp elle senkronize etmek yerine, veriyi gerçek kaynak kabul eder ve UI'ı sonucun kendisi olarak bırakırsınız.
Günlük uygulamalarda “durum” ne demektir
Durum, ekranınızın bağlı olduğu mevcut veridir: bir menünün açık olup olmadığı, forma yazılan metin, listede hangi öğelerin olduğu, hangi filtrenin seçili olduğu gibi.
Durum değiştiğinde sayfada birden çok DOM düğümü aramak zorunda kalmazsınız. Durumu güncellersiniz ve UI bununla eşleşecek şekilde yeniden render edilir.
Bu neden elle DOM işini azaltır
Geleneksel DOM-öncelikli kod sıklıkla dağıtılmış güncelleme mantığıyla sonuçlanır:
- Bir onay kutusu değişir → bir etiketi güncelle
- Bir öğe ekle → listeyi ve boş-durum mesajını güncelle
- Form gönder → butonu devre dışı bırak, spinner göster, hataları işle
React modelinde bu “güncellemeler” render çıktınızdaki koşullar haline gelir. Ekran, belirli bir durum için ne görünmesi gerektiğine dair okunabilir bir tanım olur. Bu da ekranları anlamayı, test etmeyi ve geliştirmeyi kolaylaştırır.
Küçük, ilişkilendirilebilir bir örnek
function ShoppingList() {
const [items, setItems] = useState([]);
const [text, setText] = useState("");
const add = () => setItems([...items, text.trim()]).then(() => setText(""));
return (
<section>
<form onSubmit={(e) => { e.preventDefault(); add(); }}>
<input value={text} onChange={(e) => setText(e.target.value)} />
<button disabled={!text.trim()}>Add</button>
</form>
{items.length === 0 ? <p>No items yet.</p> : (
<ul>{items.map((x, i) => <li key={i}>{x}</li>)}</ul>
)}
</section>
);
}
Boş mesajın, butonun devre dışı olma durumunun ve liste içeriğinin tümünün items ve text'ten türediğine dikkat edin. Mimari kazanç burada: veri yapısı ve UI yapısı hizalanır; bu da ekranları akıl yürütmeyi, test etmeyi ve geliştirmeyi kolaylaştırır.
Bileşenler: Yeni Yapı Taşları
React, “bileşen”i varsayılan UI çalışma birimi yaptı: markup, davranış ve stil ipuçlarını net bir arayüzün arkasında paketleyen küçük, yeniden kullanılabilir parça.
HTML şablonları, olay dinleyicileri ve CSS seçicilerini alakasız dosyalar arasında dağıtmak yerine bir bileşen bu hareketli parçaları yakın tutar. Bu her şeyin tek bir dosyada olması gerektiği anlamına gelmez—ancak kodun kullanıcının gördüğü ve yaptığı şeye göre organize edildiği anlamına gelir, DOM API'sine göre değil.
Bir bileşen gerçekte nedir
Pratikte bir bileşen genelde şunları içerir:
- Yapı (ne render ettiği)
- Etkileşim (handlerlar, durum, etkiler)
- Stil ipuçları (class isimleri, varyantlar, token'lar)
Önemli değişim: “bu div'i güncelle” diye düşünmeyi bırakıp “butonu devre dışı durumda render et” demeye başlamaktır.
Kapsülleme = daha kolay bakım ve daha net sahiplik
Bir bileşen küçük bir prop seti (girdi) ve olay/callback'ler (çıktı) açığa vurduğunda, dahiliyi değiştirmek uygulamanın geri kalanını bozmadan daha kolay olur. Ekipler belirli bileşenlerin veya klasörlerin (örneğin, “checkout UI”) sahibi olabilir ve bunları güvenle geliştirebilir.
Kapsülleme ayrıca istenmeyen bağlanmayı azaltır: daha az global seçici, daha az dosyalar arası yan etki, “neden bu click handler çalışmayı bıraktı?” sürprizleri daha az.
Bileşenler ürün kavramlarına eşlenir
Bileşenler ana yapı taşları haline gelince, kod ürünle eşleşmeye başlar:
- Button (primary/secondary, loading, icon)
- Modal (açma/kapatma, odak kilidi, escape tuşu)
- CheckoutForm (doğrulama, gönderim, hata durumları)
Bu eşleme UI tartışmalarını kolaylaştırır: tasarımcılar, PM'ler ve mühendisler aynı “şeyler” hakkında konuşabilir.
Dosya yapısına etkisi
Bileşen düşüncesi birçok kod tabanını feature- veya domain-temelli organizasyona itti (örn. /checkout/components/CheckoutForm) ve paylaşılan UI kütüphanelerine (çoğunlukla /ui/Button) yol açtı. Özellikle özellikler büyüdüğünde bu yapı sayfa-odaklı klasörlerden daha iyi ölçeklenir ve daha sonra tasarım sistemleri için zemin hazırlar.
Deklaratif Render ve JSX'in Tutuşunu Sağlaması
React'in render tarzı genellikle deklaratif olarak tanımlanır; bu, belirli bir durum için UI'ın nasıl görünmesi gerektiğini tanımladığınız ve React'in tarayıcıyı buna uydurmanın yolunu bulduğu anlamına gelir.
“Sonucu tanımla, adımları değil”
Eski DOM-öncelikli yaklaşımlarda genelde adım adım talimat yazardınız:
- bir elementi bul
- yeni bir düğüm oluştur
- metnini ayarla
- ekle
- sonra güncelle veya kaldır
Deklaratif render ile sonucu ifade edersiniz:
Kullanıcı giriş yaptıysa adını göster; yapmadıysa “Giriş yap” butonunu göster.
Bu kayma önemlidir çünkü yaptığınız “UI defterciliği” miktarını azaltır. Hangi elementlerin var olduğunu ve neyin güncellenmesi gerektiğini sürekli takip etmek yerine uygulamanızın olabileceği durumlara odaklanırsınız.
JSX bunun benimsenmesine neden yardımcı oldu
JSX, UI yapısını onu kontrol eden mantıkla yakın yazmayı kolaylaştırır. Ayrı “şablon dosyaları” ve “mantık dosyaları” arasında gitmek yerine ilgili parçaları bir arada tutabilirsiniz: markup-benzeri yapı, koşullar, küçük biçimlendirme kararları ve olay handler'ları.
Bu co-location React'in bileşen modelinin pratik hissettiren bir nedenidir. Bir bileşen sadece bir HTML parçası veya bir JavaScript paketi değildir—o bir UI davranış birimidir.
“Bu HTML ve JS'i karıştırmak değil mi?”
Sık bir endişe JSX'in HTML ile JavaScript'i karıştırdığıdır; bu geri bir adım gibi gelebilir. Ancak JSX aslında HTML değil—JavaScript çağrılarını üreten bir sözdizimidir. Daha önemlisi React teknolojileri karıştırmıyor; birlikte değişen şeyleri gruplayarak onları birlikte tutuyor.
Mantık ve UI yapısı sıkı bağlı olduğunda (ör. “doğrulama başarısızsa hata mesajını göster”), bunları bir yerde tutmak ayrı dosyalara yaymaktan daha açık olabilir.
Deklaratif render sadece JSX ile sınırlı değil
JSX React'i erişilebilir kıldı, ama temel kavram JSX'in ötesine uzanır. React'i JSX olmadan yazabilirsiniz ve diğer framework'ler de farklı şablon sözdizimleriyle deklaratif render kullanır. Kalıcı etki zihniyettir: UI'ı durumun bir fonksiyonu olarak ele almak ve ekranı eşitleme mekaniklerini framework'e bırakmak.
Reconciliation ve Sanal DOM (Miytler Olmadan)
React'ten önce, bir bug kaynağı basitti: veri değişti ama UI değişmedi. Geliştiriciler yeni veriyi alır, doğru DOM düğümlerini manuel bulur, metinleri günceller, sınıfları değiştirir, element ekler/kaldırır ve tüm bunları kenar durumlarda tutarlı tutmaya çalışırlardı. Zamanla “güncelleme mantığı” sık sık UI'ın kendisinden daha karmaşık hale gelirdi.
React'in büyük iş akışı değişikliği şu: tarayıcıya sayfayı nasıl değiştireceğini öğretmezsiniz. Belirli bir durum için UI'ın ne olması gerektiğini tanımlarsınız ve React gerçek DOM'u buna uydurmanın yolunu bulur.
Reconciliation gerçekte ne demek
Reconciliation, React'in son render ile bu seferki render'ı karşılaştırıp tarayıcı DOM'una en küçük değişiklik setini uygulama sürecidir.
Önemli kısım React'in “Sanal DOM” kullanmasının sihirli bir performans hilesi olması değil. React size öngörülebilir bir model verir:
- Render mantığını sanki UI'ı baştan inşa ediyormuşsunuz gibi yazarsınız.
- React, kullanıcıların tam yeniden inşa maliyetini ödememesi için DOM'u kademeli olarak günceller.
Bu öngörülebilirlik geliştirici iş akışını iyileştirir: daha az manuel DOM güncellemesi, daha az tutarsız durum ve uygulama genelinde aynı kuralların takip ettiği UI güncellemeleri.
Keys: pratik çıkarım
Listeleri render ederken React eski öğeleri yeni öğelere eşleştirmek için kararlı bir yöntem ister. key bunun içindir.
{todos.map(todo => (
<TodoItem key={todo.id} todo={todo} />
))}
ID gibi sabit ve benzersiz key'ler kullanın. Öğeler yeniden sıralanabiliyorsa, araya eklenip silinebiliyorsa dizi indekslerinden kaçının—aksi halde React yanlış bileşen örneğini kullanabilir ve girdilerin yanlış değerleri korumasına sebep olabilir.
Tek Yönlü Veri Akışı: Daha Basit Bir Zihinsel Model
React'in en büyük mimari kaymalarından biri verinin tek yönlü akmasıdır: veriler üst bileşenlerden aşağı çocuklara akar. Uygulamanızın herhangi bir yerinin başka parçalara doğrudan erişip paylaşılan durumu değiştirmesine izin vermek yerine, React güncellemeleri açık olaylar olarak yukarı göndermeyi teşvik eder; sonuç verisi aşağı doğru akar.
Basit bir ebeveyn/çocuk örneği
Ebeveyn durumun sahibi olur ve bunu prop olarak çocuğa geçirir. Çocuk bir değişiklik istemek için callback çağırır.
function Parent() {
const [count, setCount] = React.useState(0);
return (
<Counter
value={count}
onIncrement={() => setCount(c => c + 1)}
/>
);
}
function Counter({ value, onIncrement }) {
return (
<button onClick={onIncrement}>
Clicks: {value}
</button>
);
}
Dikkat edin: Counter count'ı doğrudan değiştirmez. value (veri) ve onIncrement (değişiklik isteme yolu) alır. Bu ayrım zihinsel modelin özüdür.
Daha net sınırlar, daha az yan etki
Bu desen sınırları belirgin hale getirir: “Bu verinin sahibi kim?” sorusu genellikle “en yakın ortak ebeveyn” tarafından cevaplanır. Bir şey beklenmedik şekilde değiştiğinde, bunu gizli mutasyonları takip etmek yerine durumun tutulduğu yerde izlersiniz.
Props vs durum organizasyon ilkesi
- Durum: bileşenin özel, değişebilir verisi (gerçek kaynak).
- Props: dışarıdan gelen girdiler (alıcı açısından salt okunur).
Bu ayrım ekiplerin mantığın nereye ait olduğuna karar vermesine yardımcı olur ve istenmeyen bağlanmayı önler.
Tekrar kullanım ve test kolaylaşır
Props'a dayanan bileşenler global değişkenlere veya DOM sorgularına bağlı olmadıkları için tekrar kullanımı kolaydır. Test etmek daha basittir: belirli prop'larla render edip çıktıyı doğrulayabilirsiniz; durumlu davranış ise durumu yöneten yerde test edilir.
Gerçek Projelerde Kompozisyon, Kalıtımdan Üstündür
React ekipleri UI için sınıf hiyerarşileri yerine küçük, odaklanmış parçaları birleştirme yönünde itti. Temel Button'ı on varyasyona genişletmek yerine genellikle bileşenleri birleştirerek davranış ve görselliği oluşturursunuz.
Günlükte kompozisyon nasıl görünür
Yaygın bir desen, veri hakkında hiçbir şey bilmeyen düzen bileşenleri oluşturmaktır:
PageShell(header/sidebar/footer)Stack/Grid(boşluk ve hizalama)Card(tutarlı çerçeve)
Bu bileşenler children kabul eder, böylece sayfa içine ne konacağını belirler.
Ayrıca RequireAuth veya ErrorBoundary gibi hafif sarmalayıcılar göreceksiniz; bunlar sarmaladıkları şeyi değiştirmeden etrafına bir endişe ekler.
Daha fazla kontrol gerektiğinde ekipler genellikle prop'lar yoluyla slot-benzeri bir yaklaşım kullanır:
Modaliçintitle,footervechildrenTableiçinrenderRowveyaemptyState
Bu, bileşenleri esnek tutar ve API yüzeyinin patlamasını engeller.
Neden kalıtım genelde zarar verir
Derin kalıtım ağaçları iyi niyetle başlar (“temel sınıfı yeniden kullanacağız”), ama yönetmesi zorlaşır çünkü:
- davranış birden fazla seviyeye dağılır (“bu stil nereden geliyor?”)
- temel sınıfa yapılan değişiklikler alakasız ekranlara yayılır
- override'lar birikir ve “genel” temel sınıf karışık hale gelir
Modern kompozisyon araçları: hook'lar
Hook'lar kompozisyonu daha pratik hale getirdi. useDebouncedValue veya usePermissions gibi özel hook'lar, birden fazla özellik bileşeninin UI'ı paylaşmadan mantık paylaşmasını sağlar. Bunu paylaşılan UI primitifleri (butonlar, input'lar, tipografi) ve özellik bileşenleri (CheckoutSummary, InviteUserForm) ile birleştirdiğinizde, uygulama büyüdükçe anlaşılır kalan tekrar kullanım elde edersiniz.
Durum Yönetimi: Yerel Durumdan Paylaşılan Store'lara
React ile başlamak için doğal yol genelde yerel bileşen durumudur: bir form alanının değeri, açılan bir dropdown, bir yükleme spinner'ı. Bu iyi çalışır—ta ki uygulama büyüyüp birden fazla UI parçasının senkron kalması gerekene kadar.
Neden durum paylaşmak zorlaşır
Özellikler genişledikçe durum sık sık doğrudan ebeveyn-çocuk ilişkisi olmayan bileşenler tarafından okunup güncellenmesi gerekir. “Sadece prop geçir” uzun prop zincirlerine dönüşebilir; bu, refaktörlemeyi riskli hale getirir, boilerplate'i artırır ve iki yerin “aynı” durumu farklı şekilde temsil ettiği kafa karıştırıcı hatalara yol açar.
Ekiplerin kullandığı yaygın yaklaşımlar
- Durumu yukarı taşımak
Durumu en yakın ortak ebeveyne taşıyın ve prop olarak aşağı geçirin. Genelde en basit seçenektir ve bağımlılıkları açık tutar, ama aşırı kullanılırsa “god component”lara yol açabilir.
- Context ile paylaşılan, uygulama-genişi endişeler
React Context birçok bileşenin aynı değere ihtiyaç duyduğu yerlerde yardımcıdır (tema, locale, mevcut kullanıcı). Prop zincirini azaltır, ama sık değişen veriyi context'e koyarsanız güncellemeleri ve performansı izlemeyi zorlaştırabilir.
- Harici store'lar
React uygulamaları büyüdükçe ekosistem Redux ve benzeri store desenleriyle yanıt verdi. Bunlar durumu merkezileştirir, genelde aksiyonlar ve seçiciler etrafında kurallar koyar; bu da büyük ölçekte öngörülebilirliği artırabilir.
Neyin uygun olduğuna karar vermek
Varsayılan olarak yerel durumu tercih edin, kardeşlerin koordinasyonu gerekirse durumu yükseltin, çapraz-kesit endişeler için context kullanın ve birçok uzak bileşenin aynı veriye ihtiyacı varsa dışsal store düşünün. “Doğru” seçim trendlerden çok uygulama karmaşıklığı, ekip büyüklüğü ve gereksinimlerin değişme sıklığına bağlıdır.
React’in Popülerleştirdiği Araçlar ve İş Akışları
React yalnızca yeni bir UI yazma yolu getirmedi—ekipleri kod, stil ve davranışın küçük, test edilebilir birimler olarak geliştirildiği bir bileşen-odaklı iş akışına itti. Bu kayma frontend projelerinin nasıl inşa edildiğini, doğrulandığını, belgelendiğini ve dağıtıldığını etkiledi.
Günlük iş akışında bileşen-odaklı geliştirme
UI bileşenlerden oluştuğunda, kenardan içe doğru çalışmak doğal hale gelir: bir buton inşa et, sonra bir form, sonra bir sayfa. Ekipler bileşenleri açık API'leri (props), öngörülebilir durumları (loading, empty, error) ve yeniden kullanılabilir stil kurallarıyla ürün gibi ele almaya başladı.
Pratik bir değişim: tasarımcılar ve geliştiriciler ortak bir bileşen envanterinde hizalanabilir, davranışı izole şekilde inceleyebilir ve sayfa düzeyinde son dakika sürprizlerini azaltabilir.
Norm haline gelen araç yığını
React'in popülerliği birçok ekibin artık standart kabul ettiği modern araç zincirini de yaygınlaştırdı:
- hızlı yerel iterasyon için bundler'lar ve dev sunucular (hot reload, code splitting)
- büyük bileşen kod tabanlarını tutarlı kılmak için lint ve formatlayıcılar
- bileşen prop'larını ve durumu yanlış kullanmayı zorlaştırmak için tip kontrolü (çoğunlukla TypeScript)
- test koşucular ve bileşen-odaklı test araçları
Aynı araçları seçmeseniz de beklenti şu: bir React uygulamasının UI regresyonlarını erken yakalayacak korunaklara sahip olması beklenir.
Bazı ekipler bu “iş akışı-öncelikli” yaklaşıma ek olarak Koder.ai gibi sohbet odaklı plan akışı ile React ön yüzlerini (ve bunların etrafındaki backend'i) hızlıca iskeletlemek için platformlar kullanıyor—bileşen yapısını, durum sahipliğini ve özellik sınırlarını haftalarca elle altyapı kurmadan hızlıca doğrulamak istediğinizde kullanışlı olabilir.
“Bileşen dokümanları” ve izole önizlemeler
React ekipleri ayrıca bileşenleri farklı durumlarda render edip not ekleyebileceğiniz ve kullanım yönergeleri için tek kaynak paylaşabileceğiniz bir bileşen keşif ortamı fikrini popülerleştirdi.
Bu “Storybook tarzı” düşünce (herhangi bir özel ürünü gerektirmeden) işbirliğini değiştirir: bir bileşenin davranışını sayfaya bağlamadan önce inceleyebilir ve kenar durumları kasıtlı olarak doğrulayabilirsiniz.
Tekrar kullanılabilir bir kütüphane inşa ediyorsanız, bu yaklaşım bir tasarım sistemiyle doğal olarak eşleşir—bakınız /blog/design-systems-basics.
İş akışının sürümlere etkisi
Bileşen-odaklı araçlar daha küçük pull request'ler, daha net görsel inceleme ve daha güvenli refaktörler teşvik eder. Zamanla ekipler, iyi tanımlanmış parçalarda iterasyon yaptıkları için UI değişikliklerini daha hızlı yayınlarlar; sayfa-genişi, dolaşık DOM kodunda gezinmek yerine.
Tasarım Sistemleri ve Yeniden Kullanılabilir Bileşen Kütüphaneleri
Pratikte bir tasarım sistemi iki şeyin birlikte çalışmasıdır: yeniden kullanılabilir UI bileşenlerinin bir kütüphanesi (butonlar, formlar, modal'lar, navigasyon) ve bunların ne zaman nasıl kullanılacağını açıklayan yönergeler (boşluk, tipografi, ton, erişilebilirlik kuralları, etkileşim kalıpları).
React bu yaklaşımı doğal hissettirdi çünkü “bileşen” zaten UI'ın temel birimidir. Markup'ı sayfalar arasında kopyalamak yerine ekipler bir \u003cButton /\u003e, \u003cTextField /\u003e veya \u003cDialog /\u003e'yi bir kez yayınlayıp her yerde yeniden kullanabilir—prop'lar aracılığıyla kontrollü özelleştirmeye izin vererek.
Neden React UI kütüphanelerine iyi uyar
React bileşenleri kendi içinde kapalıdır: yapı, davranış ve stili kararlı bir arayüzün arkasında paketleyebilirler. Bu bir bileşen kütüphanesini kolaylaştırır:
- Dokümante: her bileşenin örnekleri ve kullanım notları olabilir
- Sürüm kontrollü: değişiklikler kademeli olarak yayınlanabilir
- Kompozit: küçük parçalar daha büyük kalıplara dönüşür (örn. alanlar + doğrulama + düzen)
Sıfırdan başlıyorsanız, bir yığın bileşenin tutarsız bir karmaşaya dönüşmesini engellemek için basit bir kontrol listesi yardımcı olur: /blog/component-library-checklist.
Tutarlılık kazanır: erişilebilirlik, tema, paylaşılan davranış
Bir tasarım sistemi yalnızca görsel tutarlılık değildir—davranışsal tutarlılıktır da. Bir modal her zaman odağı doğru şekilde kilitlediğinde veya bir dropdown her zaman klavye ile gezinebildiğinde, erişilebilirlik sonradan eklenen bir şey değil varsayılan olur.
Theming de kolaylaşır: token'ları (renkler, boşluk, tipografi) merkezileştirip bileşenlerin bunları tüketmesini sağlayabilirsiniz; böylece marka değişiklikleri her ekranı ayrı ayrı değiştirmeyi gerektirmez.
Paylaşılan bileşenlere yatırım yapmanın değip değmeyeceğini değerlendiren ekipler genelde bunu ölçek ve bakım maliyetleri ile ilişkilendirir; bazı organizasyonlar bu değerlendirmeyi platform planlarına bağlar: /pricing.
Test, Performans ve Yaygın Mimari Tuzakları
React yalnızca nasıl UI inşa ettiğimizi değiştirmedi—kaliteyi nasıl değerlendirdiğimizi de değiştirdi. Uygulama bileşenlerden oluştuğunda ve bileşenlerin net girdileri (props) ve çıktıları (render edilmiş UI) olduğunda, test ve performans artık mimari kararlar haline gelir, son dakika düzeltmeleri değil.
Sınırlar gerçek olduğunda testler basitleşir
Bileşen sınırları iki faydalı seviyede test yapmayı sağlar:
- Birim testleri: belirli prop ve durumlar için bir bileşenin doğru render edip etmediğini doğrularsınız (kenar durumlar dahil). Bileşenleri küçük “UI fonksiyonları” gibi ele alabilirsiniz.
- Entegrasyon testleri: küçük bir ağaç render edip (ör. bir form ve doğrulama mesajı, bir liste ve filtreler) kullanıcı davranışının doğru UI değişikliklerini ürettiğini doğrularsınız.
Bu, bileşenlerin net sahiplike sahip olduğu durumlarda en iyi şekilde çalışır: bir yer durumun sahibi olsun, çocuklar çoğunlukla veriyi gösterip olay yayınlasın.
Performans mikro-optimizasyon değil, mimaridir
React uygulamaları genelde hızlı hissettirir çünkü ekipler performansı yapının bir parçası olarak planlar:
- Kod bölme: sadece bir rota veya özellik neye ihtiyaç duyuyorsa onu yükleyin, başlangıç boyutu küçük kalsın.
- Memoizasyon: girdiler değişmediğinde gereksiz yeniden render'ları önleyin (kasıtlı, her yere değil).
- Lazy loading: ağır widget'ları (grafikler, editörler) kullanıcı ihtiyaç duyduğunda erteleyin.
Kullanışlı bir kural: pahalı parçaları (uzun listeler, karmaşık hesaplamalar, sık yeniden render edilen alanlar) optimize edin; küçük kazanımların peşinden koşmayın.
Dikkat edilmesi gereken tuzaklar
Zaman içinde ekipler şu tuzaklara kayabilir: aşırı bileşenleştirme (amaçsız çok küçük parçalar), prop drilling (veriyi birçok katmandan geçirmek) ve hangi bileşenin durumu “sahiplendiği”nin belirsizleştiği bulanık sınırlar.
Hızlı ilerlerken (özellikle otomatik oluşturulmuş veya scaffold edilmiş kodla) bu tuzaklar daha hızlı ortaya çıkar: bileşenler çoğalır ve sahiplik bulanıklaşır. Elle kod yazarken veya Koder.ai gibi bir araçla React uygulaması ve backend (çoğunlukla Go ile PostgreSQL) üretilse de korunak aynıdır: durum sahipliğini açık tutun, bileşen API'lerini küçük tutun ve net özellik sınırlarına doğru refaktör yapın.
Gelecek ne getirir (ve kalıcı olan ne)
Server Components, meta-framework'ler ve daha iyi araçlar React uygulamalarının teslimatını geliştirmeye devam edecek. Kalıcı ders değişmedi: durumu, sahipliği ve bileşen bazlı yapı taşlarını merkeze koyun; test ve performansı doğal olarak buna göre şekillendirin.
Daha derin yapı kararları için bkz. /blog/state-management-react.
SSS
React bağlamında “frontend mimarisi” ne anlama geliyor?
React, önyüz mimarisini birkaç temel karar etrafında yeniden tanımladı:
- UI'yı yeniden kullanılabilir bileşenlere bölmek
- UI'ı durum odaklı yapmak (veri kaynak kabul edilir)
- ekranları oluşturmak için kompozisyon kullanmak
- sahipliği netleştirmek için tek yönlü veri akışı benimsemek
Pratik etkisi: elle DOM ile uğraşmayı azaltmak ve ekipler ile araçlar için daha net sınırlar oluşturmaktır.
Pratik bir tanımla “bileşen düşüncesi” nedir?
Bileşen düşüncesi, her UI parçasını kendi render'ından sorumlu, küçük ve tekrar kullanılabilir bir birim olarak ele almak ve bunları daha büyük ekranlar oluşturmak için birleştirebilmektir. Pratikte bir bileşen şunları kapsar:
- yapı (ne render ettiği)
- etkileşim (handlerlar, durum, yan etkiler)
- stil için ipuçları (class/variant/tokenlar)
Bu yaklaşım işi “bu DOM düğümünü güncelle”den “bu duruma göre bu bileşeni render et”e kaydırır.
React neden manuel DOM manipülasyonunu azalttı?
DOM-öncelikli kodda DOM genellikle “gerçek kaynak” haline gelir ve birden çok elementi elle senkronize etmek gerekir. React’te durum güncellenir ve UI buna göre render edilir; böylece yükleme göstergeleri, devre dışı butonlar ve boş durumlar doğal olarak tutarlı kalır.
İyi bir test: eğer sık sık “eleman bul ve sınıfı değiştir” adımları yazıyorsanız modeli zorlamış olursunuz; UI durumdan çıkıyorsa genellikle durum sahipliğiyle ilgilidir.
React öncesi, DOM-öncelikli mimarilerin en büyük sorunları nelerdi?
React öncesinde birçok uygulama sayfa merkezliydi: sunucu tarafı şablonlar, jQuery ve eklentiler. Davranış server-side görünümler, HTML öznitelikleri ve JS başlatıcıları arasında dağınıktı.
Yaygın problemler şunlardı:
- şablonlar/ sayfalar arasında tekrarlanan UI
- işaretleme değiştiğinde bozulan hassas seçiciler
- eşleşmeyen UI durumları (spinner/hata/ buton uyumsuzluğu)
React ekipleri yeniden kullanılabilir bileşenler ve tahmin edilebilir güncellemeler yönüne itti.
“Deklaratif render” ne demektir ve neden önemlidir?
Deklaratif render etme, belirli bir durum için UI'ın nasıl görünmesi gerektiğini tanımlamaktır; DOM'u adım adım nasıl değiştireceğinizi yazmak değil.
Eski akışta:
- düğüm oluştur → metin ayarla → ekle → sonra kaldır
Deklaratifte render çıktısında koşulları ifade edersiniz (ör. “giriş yapılmışsa ismini göster, değilse 'Giriş yap' butonu göster”), ve React gerçek DOM'u günceller.
JSX, React modelinin benimsenmesine nasıl yardımcı oldu?
JSX, UI yapısını onu kontrol eden mantıkla (koşullar, biçimlendirme, handlerlar) birlikte yazmayı kolaylaştırdı. Bu, ayrı şablon ve mantık dosyaları arasında gidip gelmeyi azalttı.
JSX HTML değil; JavaScript çağrılarına dönüşen bir sözdizimidir. En önemli fayda organizasyoneldir: birlikte değişen şeyleri (UI + davranış) aynı bileşende toplamak, bakımı kolaylaştırır.
React reconciliation nedir ve `key`lerin gerçek amacı nedir?
Reconciliation, React'in önceki render ile yeni render'ı karşılaştırıp tarayıcı DOM'una en küçük değişiklik setini uygulama sürecidir.
İşin pratik kısmı öngörülebilirliktir: render mantığını her seferinde baştan yazıyormuş gibi yazarsınız, React ihtiyaç duyulan farkları uygulayan kısımdır.
Listeler için key kullanımı pratik açıdan şudur: eski ve yeni öğeleri eşleştirmek için kararlı bir işaret gerekir. Benzersiz ve sabit key (örn. ID) kullanın; dizinleri, öğeler yeniden sıralanıp eklenip silinebiliyorsa kullanmayın, çünkü yanlış bileşen örnekleri yeniden kullanılabilir.
Tek yönlü veri akışı React uygulaması mimarisini nasıl sadeleştirir?
Tek yönlü veri akışı, verinin üst bileşenlerden çocuklara props ile aktığı ve çocukların değişiklik istemek için geriye olaylar/callback'lar gönderdiği anlamına gelir.
Bu sınırları netleştirir: “Bu verinin sahibi kim?” sorusunun cevabı genelde “en yakın ortak üst”tur. Hata ayıklama, gizli mutasyonları takip etmek yerine verinin nerede tutulduğunu bulmak olur.
Gerçek projelerde “kompozisyon, kalıtımdan üstündür” neye benzer?
Kompozisyon, ekranları küçük, odaklanmış parçaları birleştirerek kurmak demektir; derin sınıf hiyerarşileri yerine bileşenleri bir araya getirirsiniz.
Günlük örnekler:
PageShell(header/yan panel/footer)Stack/Grid(boşluk ve hizalama)Card(tutarlı çerçeve)
Bunlar children alır; sayfa ne koyacağını belirler. Slot benzeri prop'lar (title, footer, emptyState) da sık kullanılır.
Bu yaklaşım, kalıtımın getirdiği karmaşıklıktan kaçınır.
Bir React uygulaması büyüdükçe ekipler durum yönetimine nasıl yaklaşmalı?
Pratik bir ilerleme şöyle olur:
- bileşen-özgü UI için yerel durum
- kardeşlerin koordinasyonu gerekince durumu yükseltme
- çapraz-kesit endişeler için Context (tema, locale, kullanıcı)
- birçok uzak bileşenin aynı veriye ihtiyaç duyduğu ve daha sıkı güncelleme kuralları gerektiğinde dışsal store'lar (örn. Redux benzeri)
Seçimi uygulama karmaşıklığı, ekip büyüklüğü ve gereksinimlerin değişme sıklığı belirler; trendlere göre değil ihtiyaçlara göre karar verin.