React projelerinde tekrarlayan kod yazmaktan sıkıldınız mı? Kodlama hızınızı artıracak ve geliştirme sürecinizi sorunsuz hale getirecek 50 kullanışlı React snippet’ı ile tanışmaya hazır olun. Bu makale, her seviyeden geliştiriciye pratik çözümler sunuyor.
Modern web geliştirme dünyasında hız ve verimlilik, başarı için vazgeçilmez iki unsurdur. Özellikle React gibi bileşen tabanlı kütüphanelerle çalışırken, sürekli olarak aynı kalıpları tekrarlamak hem zaman alıcı hem de yorucu olabilir. İşte tam bu noktada, “snippet” adı verilen küçük, yeniden kullanılabilir kod parçacıkları devreye giriyor. Peki, React snippet’ları neden bu kadar değerli ve geliştirme akışınızda nasıl devrim yaratabilir?
React snippet’ları, genellikle sık kullanılan React kalıplarını, Hook’ları, bileşen yapılarını veya yardımcı işlevleri tek bir komutla otomatik olarak oluşturan kısa kod şablonlarıdır. Bir düğmeye basarak veya birkaç karakter yazarak, saatler sürecek manuel kodlamadan kurtulabilir ve uygulamanızın temelini hızla oluşturabilirsiniz. Bu, sadece yazım hatalarını azaltmakla kalmaz, aynı zamanda projelerinizde tutarlı bir kodlama standardı sağlamanıza da yardımcı olur. Örneğin, bir useState Hook’u tanımlamak için her seferinde import React, { useState } from 'react';, const [state, setState] = useState(initialValue); gibi satırları yazmak yerine, basit bir kısayol ile bunları anında oluşturabilirsiniz. Bu tür otomasyonlar, özellikle büyük ve karmaşık React uygulamaları geliştirirken paha biçilmez bir avantaj sunar.
Bu makale boyunca, React’in temel yapı taşlarından ileri seviye Hook’larına, veri yönetiminden performans optimizasyonuna kadar birçok alanda size yardımcı olacak en faydalı snippet’ları keşfedeceğiz. Yeni başlayanlar için React’in temel kavramlarına hızlı bir giriş yaparak başlayacak, ardından deneyimli geliştiricilerin bile gözden kaçırmış olabileceği ileri düzey tekniklere odaklanacağız. Amacımız, sadece kod örnekleri sunmak değil, aynı zamanda bu snippet’ları kendi projelerinizde nasıl etkin bir şekilde kullanabileceğinize dair pratik bilgiler ve gerçek dünya senaryoları sunmaktır. Bu sayede, React geliştirme sürecinizi hızlandırırken aynı zamanda daha temiz, daha sürdürülebilir ve daha performanslı uygulamalar inşa etmenize yardımcı olmayı hedefliyoruz.
React, modern web uygulamaları geliştirmek için tercih edilen en popüler JavaScript kütüphanelerinden biridir. Temel olarak, kullanıcı arayüzlerini (UI) bildirimsel bir yaklaşımla oluşturmanızı sağlar. Bu da, uygulamanızın belirli bir anda nasıl görünmesi gerektiğini tanımladığınızda, React’in altta yatan DOM manipülasyonlarını otomatik olarak halletmesi anlamına gelir. React’in kalbinde “bileşenler” (components) bulunur. Bu bileşenler, bağımsız ve yeniden kullanılabilir kod parçalarıdır ve kendi mantıklarını ve görünümlerini kapsüllerler. Örneğin, bir “Button” bileşeni, bir “Navbar” bileşeni veya bir “UserProfile” bileşeni düşünebilirsiniz. Bu bileşenler, JSX adı verilen JavaScript sözdizimi uzantısıyla yazılır. JSX, JavaScript içinde HTML benzeri yapılar yazmanıza olanak tanır ve bu da kullanıcı arayüzünü tanımlamayı sezgisel hale getirir. Örneğin:
function Merhaba({ isim }) {
return Merhaba, {isim}!
;
}
Bu örnekte, Merhaba adlı bir fonksiyonel bileşen görüyoruz. isim bir "prop"tur, yani üst bileşenden bu bileşene aktarılan veridir. Bileşenlerin durumu (state) ise, zamanla değişebilen ve bileşenin yeniden render edilmesine neden olabilen dahili verilerdir. React Hook'ları (useState, useEffect vb.) bu durumu ve diğer React özelliklerini fonksiyonel bileşenlerde kullanmanın yolunu sunar. Şimdi, bu temel yapı taşlarını daha verimli kullanmamızı sağlayacak pratik snippet'lara dalalım.
Temel React Hook'ları ile Verimli Kodlama: useState ve useEffect'in Gücü
React'in Hook'ları, fonksiyonel bileşenlerde durum (state) ve yaşam döngüsü özelliklerini kullanmamızı sağlayarak geliştirme şeklimizde devrim yarattı. useState ve useEffect, bu Hook'ların temelini oluşturur ve günlük React geliştirme pratiğimizin vazgeçilmez bir parçasıdır. Bu bölümde, bu temel Hook'ları daha hızlı ve hatasız bir şekilde entegre etmenizi sağlayacak snippet'ları inceleyeceğiz.
useState Snippet'ları: Bileşen Durumunu Kolayca Yönetin
useState, bir fonksiyonel bileşende durum eklemenizi sağlayan Hook'tur. Bir değeri ve bu değeri güncelleyecek bir fonksiyonu döndürür. İşte tipik bir useState kullanım senaryosu için snippet:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // SFN: stateFunctionNumber
// const [data, setData] = useState({}); // SFO: stateFunctionObject
// const [items, setItems] = useState([]); // SFA: stateFunctionArray
// const [isVisible, setIsVisible] = useState(false); // SFB: stateFunctionBoolean
const increment = () => {
setCount(prevCount => prevCount + 1);
};
return (
Sayaç: {count}
);
}
Bu snippet, bir sayısal durum (count) ve onu güncellemek için bir fonksiyon (setCount) tanımlar. Çoğu IDE uzantısı (örneğin VS Code için "ES7 React/Redux/GraphQL/React-Native snippets"), usf yazıp Tab tuşuna basarak benzer bir yapıyı otomatik olarak oluşturmanıza olanak tanır. useState ile ilgili diğer faydalı snippet'lar, başlangıç değeri olarak nesneler, diziler veya boolean değerleri tanımlamanıza yardımcı olabilir. Örneğin, bir boolean durumu için usb (useStateBoolean), bir nesne için uso (useStateObject) gibi kısayollar mevcuttur. Bu sayede, her seferinde tam sözdizimini yazmak yerine, sadece birkaç tuş darbesiyle ihtiyacınız olan durum tanımını hızlıca oluşturabilirsiniz.
useEffect Snippet'ları: Yan Etkileri Verimli Şekilde Yönetin
useEffect Hook'u, bileşen yaşam döngüsü metotlarının (örneğin componentDidMount, componentDidUpdate, componentWillUnmount) fonksiyonel bileşenlerdeki karşılığıdır. Veri çekme, DOM manipülasyonları veya aboneliklerin ayarlanması gibi "yan etkileri" yönetmek için kullanılır. İşte temel bir useEffect snippet'ı:
import React, { useState, useEffect } from 'react'; function DataFetcher() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { // USEF: useEffect function const fetchData = async () => { try { const response = await fetch('https://api.example.com/items'); if (!response.ok) { throw new Error(HTTP error! status: ${response.status}); } const result = await response.json(); setData(result); } catch (e) { setError(e); } finally { setLoading(false); } }; fetchData(); // Opsiyonel temizleme fonksiyonu (componentWillUnmount) return () => { // Örneğin, bir aboneliği temizle console.log('Bileşen ayrıldı, temizlik yapılıyor...'); }; }, []); // Bağımlılık dizisi boş olduğu için sadece bir kere çalışır (componentDidMount) if (loading) returnVeriler yükleniyor...
; if (error) returnHata: {error.message}
; return (Çekilen Veriler
{JSON.stringify(data, null, 2)});
}
Bu snippet, bir API'den veri çekme ve yükleme/hata durumlarını yönetme senaryosunu göstermektedir.
useEffect'in bağımlılık dizisi (ikinci argümanı) oldukça önemlidir. Boş bir dizi[]ile, efektin yalnızca bileşenin ilk render'ında çalışmasını (componentDidMountbenzeri) sağlarsınız. Eğer bağımlılıkları eklerseniz, bu bağımlılıklar değiştiğinde efekt yeniden çalışır (componentDidUpdatebenzeri). Temizleme fonksiyonu ise bileşen DOM'dan kaldırıldığında (componentWillUnmountbenzeri) çalışır ve bellek sızıntılarını önlemek için önemlidir.usefveyauseEffectgibi kısayollar, bu yapıyı saniyeler içinde oluşturmanıza olanak tanır. Ayrıca, belirli bir duruma veya prop'a bağlı olarak çalışanuseEffectiçin de hızlı snippet'lar bulmak mümkündür, bu da özellikle performans optimizasyonu veya belirli koşullarda yan etkileri tetikleme ihtiyacında büyük kolaylık sağlar.Uzman İpucu: Temizleme fonksiyonunu asla unutmayın! Özellikle harici kaynaklara (WebSocket, olay dinleyicileri) abone oluyorsanız, bellekte sızıntı oluşmasını engellemek içinuseEffect'in return fonksiyonunda bu abonelikleri kaldırdığınızdan emin olun.Vaka Analizi: Dinamik Başlıklı Bir Sayaç Bileşeni
Hem
useStatehem deuseEffect'i kullanarak dinamik bir başlık ve sayaç içeren bir bileşen geliştirelim. Bu senaryo, kullanıcı etkileşimine göre durumun nasıl değiştiğini ve bu değişimin yan etkiler aracılığıyla tarayıcı başlığını nasıl güncellediğini gösterir.import React, { useState, useEffect } from 'react'; function DynamicCounter() { const [count, setCount] = useState(0); const [isCounting, setIsCounting] = useState(false); // Sayacın değiştiğinde tarayıcı başlığını güncelleme useEffect(() => { document.title =Sayaç: ${count}; }, [count]); // count değiştiğinde yeniden çalışır // Sayacı otomatik artırma/durdurma useEffect(() => { let intervalId; if (isCounting) { intervalId = setInterval(() => { setCount(prevCount => prevCount + 1); }, 1000); } return () => { if (intervalId) { clearInterval(intervalId); } }; }, [isCounting]); // isCounting değiştiğinde yeniden çalışır return (); }Dinamik Sayaç
Mevcut Sayı: {count}
Bu örnekte, ilk
useEffect,countdurumu değiştiğindedocument.title'ı günceller. İkinciuseEffectise,isCountingdurumuna bağlı olarak bir interval başlatır veya temizler. Bu, hem duruma bağlı yan etkileri hem de temizleme fonksiyonlarının nasıl kullanıldığını net bir şekilde göstermektedir. Bu tür bir bileşeni hızlıca oluşturmak içinusf,usefgibi snippet'ları kullanarak başlangıç kodunu saniyeler içinde hazır hale getirebilirsiniz.İleri Seviye Hook'lar ve Performans Optimizasyonu: useMemo, useCallback ve useRef ile Çalışmak
React uygulamalarınızın performansı, kullanıcı deneyimi açısından kritik öneme sahiptir. Özellikle büyük ve veri yoğun uygulamalarda, gereksiz yeniden render (re-render) işlemlerini minimize etmek, uygulamanızın akıcılığını artırır. React, bu tür optimizasyonlar için
useMemo,useCallbackveuseRefgibi ileri seviye Hook'lar sunar. Bu bölümde, bu Hook'ların ne işe yaradığını ve onlarla birlikte kullanabileceğiniz pratik snippet'ları ele alacağız.useMemo ile Pahalı Hesaplamaları Ön Belleğe Alın
useMemoHook'u, pahalıya mal olan bir hesaplamanın sonucunu ön belleğe almanızı (memoize etmenizi) sağlar. Yalnızca bağımlılıkları değiştiğinde yeniden hesaplama yapar. Bu, özellikle büyük veri kümeleri üzerinde filtreleme, sıralama veya karmaşık dönüştürme işlemleri yaparken performansı artırabilir. BiruseMemosnippet'ı genellikle şu şekildedir:import React, { useMemo, useState } from 'react'; function ProductList({ products, filterTerm }) { const [searchTerm, setSearchTerm] = useState(filterTerm || ''); // useMemo ile filtrelenmiş ürün listesini ön belleğe al const filteredProducts = useMemo(() => { // UM: useMemo console.log('Ürünler filtreleniyor...'); // Sadece bağımlılıklar değişince çalışır return products.filter(product => product.name.toLowerCase().includes(searchTerm.toLowerCase()) ); }, [products, searchTerm]); // products veya searchTerm değiştiğinde yeniden hesapla return (); }Ürün Listesi
setSearchTerm(e.target.value)} style={{ width: '100%', padding: '10px', marginBottom: '20px', borderRadius: '4px', border: '1px solid #ccc' }} />{filteredProducts.map(product => (
- {product.name} - ${product.price}
))}Bu
useMemosnippet'ı,productsveyasearchTermdeğişmediği sürece filtreleme işlemini tekrar çalıştırmaz. Bu sayede, bileşen yeniden render edildiğinde (örneğin başka bir durum değiştiğinde) gereksiz CPU döngüleri harcanmaz.umgibi bir kısayol, bu yapıyı kolayca oluşturmanızı sağlar.useCallback ile Fonksiyonları Ön Belleğe Alın
useCallbackHook'u,useMemo'ya benzer ancak bir fonksiyonu ön belleğe almak için kullanılır. Bu, özellikle alt bileşenlere prop olarak geçirilen fonksiyonların gereksiz yere yeniden oluşturulmasını engeller. Bu durum,React.memoile optimize edilmiş alt bileşenlerin bileşen prop'u değişmediği sürece yeniden render edilmesini engellemeye yardımcı olur. İşte biruseCallbackörneği:import React, { useState, useCallback } from 'react'; // Alt bileşen (React.memo ile optimize edilmiş) const ChildComponent = React.memo(({ onClick }) => { console.log('ChildComponent render edildi'); return ; }); function ParentComponent() { const [count, setCount] = useState(0); const [text, setText] = useState(''); const handleClick = useCallback(() => { // UC: useCallback setCount(prevCount => prevCount + 1); }, []); // Bağımlılık dizisi boş olduğu için bu fonksiyon sadece bir kere oluşur const handleTextChange = (e) => { setText(e.target.value); }; return (); }Parent Component
Sayaç: {count}
Bu örnekte,
handleClickfonksiyonuuseCallbackile ön belleğe alınmıştır.ParentComponentyeniden render edildiğinde (örneğintextdurumu değiştiğinde),handleClickfonksiyonunun referansı değişmez. Bu sayede,React.memoile optimize edilmişChildComponentgereksiz yere yeniden render edilmez.ucallveyausecallbackgibi kısayollar bu yapıyı hızlıca oluşturur.useRef ile DOM Elementlerine ve Değişken Değerlere Erişin
useRefHook'u, doğrudan DOM elemanlarına erişmek veya bileşen render'ları arasında kalıcı olan değişken bir değeri tutmak için kullanılır.useState'den farklı olarak,useRefdeğeri değiştiğinde bileşenin yeniden render edilmesine neden olmaz. İşte biruseRefkullanım senaryosu:import React, { useRef } from 'react'; function FocusInput() { const inputRef = useRef(null); // URF: useRef const focusInput = () => { inputRef.current.focus(); // DOM elementine doğrudan erişim }; return (); }Input'u Odakla
Bu snippet'ta,
inputRefdeğişkeni birinputelemanına bağlanır.focusInputfonksiyonu çağrıldığında,inputRef.current.focus()ile doğrudan DOM elemanına erişilerek ona odaklanılır.urgibi kısayollar,useReftanımlamalarını hızlandırır.Uzman İpucu:useRef'i sadece DOM manipülasyonları için değil, aynı zamanda bileşen render'ları arasında kalıcı olması gereken ancak yeniden render tetiklememesi gereken değerleri (örneğin, bir zamanlayıcı ID'si) depolamak için de kullanabilirsiniz.Vaka Analizi: Optimize Edilmiş Bir Filtreleme Bileşeni
Bir ürün listesini filtreleyen bir bileşen düşünelim. Hem
useMemohem deuseCallbackkullanarak performansı nasıl optimize edebileceğimize bakalım. Bu örnek, pahalı filtreleme işlemini ve alt bileşenlere geçen callback fonksiyonunu optimize eder.import React, { useState, useMemo, useCallback } from 'react'; const ProductItem = React.memo(({ product, onSelect }) => { console.log(ProductItem ${product.name} render edildi); return ({product.name} - ${product.price} ); }); function OptimizedProductFilter({ initialProducts }) { const [searchTerm, setSearchTerm] = useState(''); const [selectedProductId, setSelectedProductId] = useState(null); const handleSearchChange = (e) => { setSearchTerm(e.target.value); }; // Pahalı filtreleme işlemini useMemo ile ön belleğe al const filteredProducts = useMemo(() => { console.log('Ürünler useMemo ile filtreleniyor...'); if (!searchTerm) { return initialProducts; } return initialProducts.filter(product => product.name.toLowerCase().includes(searchTerm.toLowerCase()) ); }, [initialProducts, searchTerm]); // initialProducts veya searchTerm değiştiğinde yeniden hesapla // onSelect fonksiyonunu useCallback ile ön belleğe al const handleProductSelect = useCallback((productId) => { console.log(Ürün seçildi: ${productId}); setSelectedProductId(productId); }, []); // Bağımlılık yok, bu fonksiyon sadece bir kere oluşur return (); }Optimize Edilmiş Ürün Filtreleme
Seçilen Ürün ID: {selectedProductId || 'Yok'}
{filteredProducts.map(product => ( ))}
Bu vaka analizinde,
filteredProductslistesi sadeceinitialProductsveyasearchTermdeğiştiğinde yeniden hesaplanır.handleProductSelectfonksiyonu iseuseCallbacksayesinde tek bir referansa sahip olur veOptimizedProductFilterbileşeni yeniden render edildiğinde bile yeni bir fonksiyon olarak oluşturulmaz. Bu daProductItembileşenlerinin,productprop'u veyaonSelectprop'u gerçekten değişmediği sürece gereksiz yere yeniden render edilmesini engeller. Bu tür optimizasyonlar, özellikle yüzlerce veya binlerce öğe içeren listelerde ve karmaşık UI'larda fark yaratır.Bileşenler Arası Veri Akışı ve Yönetimi: Context API ve Prop Drilling Çözümleri
React uygulamaları büyüdükçe, bileşenler arası veri paylaşımı karmaşık hale gelebilir. Özellikle, bir verinin birçok katmanlı bileşenden geçerek aşağıya doğru aktarılması anlamına gelen "prop drilling" sorunu sıkça karşımıza çıkar. Bu durum, kodu okunması ve bakımı zor hale getirebilir. React'in
Context API'si, bu soruna zarif bir çözüm sunar. Bu bölümde,Context API'nin temelini ve onunla birlikte kullanabileceğiniz pratik snippet'ları inceleyeceğiz.Context API Temelleri: Provider ve Consumer/useContext
Context API, verileri bileşen ağacında manuel olarak prop'larla geçmeden, doğrudan paylaşmanıza olanak tanır. Genellikle tema tercihleri, kullanıcı kimlik doğrulama durumu veya dil ayarları gibi global veriler için kullanılır. Bir Context oluşturmak ve kullanmak için temel adımlar şunlardır:
createContextile bir Context oluşturun.- Verileri sağlayacak bir
Providerbileşeni kullanın.- Verilere erişmek için
useContextHook'unu (fonksiyonel bileşenlerde) veyaConsumerbileşenini (sınıf bileşenlerinde) kullanın.İşte bir tema Context'i için temel snippet'lar:
// 1. Context Oluşturma (e.g., ThemeContext.js) import React, { createContext, useState, useContext } from 'react'; const ThemeContext = createContext(null); // RTC: React Theme Context export const ThemeProvider = ({ children }) => { // RTCP: React Theme Context Provider const [theme, setTheme] = useState('light'); const toggleTheme = () => { setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light')); }; const contextValue = { theme, toggleTheme }; return ( {children} ); }; // 2. Context'i Kullanma (e.g., ThemeToggleButton.js) export const useTheme = () => { // RTCC: React Theme Context Consumer (custom hook) const context = useContext(ThemeContext); if (!context) { throw new Error('useTheme must be used within a ThemeProvider'); } return context; };Bu snippet'lar, bir tema Context'i oluşturmanın ve onu bir
ThemeProvideraracılığıyla uygulamanın geri kalanına sağlamanın temel yapısını gösterir. Ayrıca,useThemeadında basit bir custom hook oluşturarak Context'e erişimi kolaylaştırır.rtc(React Theme Context) veyarcp(React Context Provider) gibi kısayollar, bu boilerplate kodu hızla oluşturmanıza yardımcı olabilir.Vaka Analizi: Global Tema Yönetimi ile Prop Drilling'e Son
Bir uygulamanın tema ayarını (açık/koyu mod) global olarak yönettiğimizi varsayalım. Bu ayar, birçok farklı bileşen tarafından kullanılacak ve değiştirilebilecektir.
Context API'yi kullanarak bu durumu nasıl yöneteceğimizi görelim.// App.js import React from 'react'; import { ThemeProvider, useTheme } from './ThemeContext'; // ThemeContext.js'den import import { ReactComponent as SunIcon } from './icons/sun.svg'; // SVG ikonlar (örnek) import { ReactComponent as MoonIcon } from './icons/moon.svg'; // SVG ikonlar (örnek) // Tema düğmesini içeren bir alt bileşen function ThemeToggleButton() { const { theme, toggleTheme } = useTheme(); return ( ); } // Uygulamanın ana içeriğini gösteren bir bileşen function Content() { const { theme } = useTheme(); return (); } // Ana Uygulama Bileşeni function App() { return (Bu metin {theme === 'light' ? 'açık' : 'koyu'} tema ile görüntülendi.
); } export default App;Global Tema Yönetimi
Bu Footer bileşeni de temayı kullanabilir.
Bu örnekte,
AppbileşeniniThemeProviderile sarmalayarak, uygulamanın tüm alt bileşenlerinin tema durumuna vetoggleThemefonksiyonuna erişmesini sağladık.ThemeToggleButtonveContentbileşenleri, doğrudanuseThemecustom hook'unu kullanarak tema bilgilerine erişir. Bu, prop drilling'i tamamen ortadan kaldırır ve kodu daha modüler ve okunabilir hale getirir. Bu tür bir yapı, kullanıcı ayarları, dil tercihleri veya global bildirimler gibi verileri yönetmek için mükemmel bir çözümdür.Uzman İpucu: Context API, Redux gibi daha karmaşık durum yönetim kütüphanelerine hafif bir alternatif olabilir. Ancak çok sık güncellenen veya uygulamanın büyük bir bölümünü etkileyen karmaşık global durumlar için hala Redux gibi çözümler daha uygun olabilir. Context'i "her şeyi" yönetmek için değil, daha çok bileşen ağacında belirli bir veri türünü paylaşmak için düşünün.Form Yönetimi ve Validasyon: Kullanıcı Girdileriyle Güvenli Etkileşim
React uygulamalarında kullanıcı girdilerini toplamak ve işlemek için formlar kritik bir rol oynar. Ancak form yönetimi, özellikle validasyon (doğrulama) ve durum yönetimi söz konusu olduğunda karmaşık hale gelebilir. React'in "kontrollü bileşenler" (controlled components) yaklaşımı, form girdilerini React'in durumuyla senkronize ederek bu süreci daha yönetilebilir kılar. Bu bölümde, form yönetimi ve validasyon için en faydalı snippet'ları ve pratik yaklaşımları inceleyeceğiz.
Kontrollü Bileşenler ve Temel Form Snippet'ları
Kontrollü bir bileşen, form elemanının değerinin (örneğin bir
inputveyatextarea) React durumu tarafından kontrol edildiği bileşendir. Değer,valueprop'u ile atanır ve değişiklikleronChangeolayı ile yakalanır, ardından durum güncellenir. Bu, form verilerinin her zaman React durumunda tutulduğu anlamına gelir. İşte basit bir input için snippet:import React, { useState } from 'react'; function SimpleInputForm() { const [inputValue, setInputValue] = useState(''); // USFS: useStateFormString const handleChange = (e) => { setInputValue(e.target.value); }; const handleSubmit = (e) => { e.preventDefault(); // Sayfanın yeniden yüklenmesini engelle console.log('Gönderilen Değer:', inputValue); alert(Gönderilen Değer: ${inputValue}); setInputValue(''); // Formu sıfırla }; return ( ); }Bu snippet, bir
inputelemanının değeriniuseStateile nasıl yönetileceğini ve form gönderiminin nasıl ele alınacağını gösterir.e.preventDefault()kullanımı, tarayıcının varsayılan form gönderme davranışını engellemek için kritik öneme sahiptir.usf(useStateForm) veyaformgibi kısayollar, bir form bileşeninin temel yapısını hızlıca oluşturmanıza yardımcı olabilir.Dinamik Form Alanları ve Validasyon Snippet'ları
Birden fazla form alanı olduğunda, her biri için ayrı bir
useStatetanımlamak yorucu olabilir. Bunun yerine, tek bir nesne durumunda tüm form verilerini tutmak daha yaygın bir yaklaşımdır. Ayrıca, kullanıcı girdilerinin belirli kurallara uygun olup olmadığını kontrol etmek için validasyon eklemek önemlidir.import React, { useState } from 'react'; function MultiInputForm() { const [formData, setFormData] = useState({ // USFO: useStateFormObject username: '', email: '', password: '' }); const [errors, setErrors] = useState({}); const handleChange = (e) => { const { name, value } = e.target; setFormData(prevData => ({ ...prevData, [name]: value })); // Validasyon hatasını anında temizle if (errors[name]) { setErrors(prevErrors => { const newErrors = { ...prevErrors }; delete newErrors[name]; return newErrors; }); } }; const validate = () => { const newErrors = {}; if (!formData.username) { newErrors.username = 'Kullanıcı adı gerekli.'; } else if (formData.username.length < 3) { newErrors.username = 'Kullanıcı adı en az 3 karakter olmalı.'; } if (!formData.email) { newErrors.email = 'E-posta gerekli.'; } else if (!/\S+@\S+\.\S+/.test(formData.email)) { newErrors.email = 'Geçerli bir e-posta adresi girin.'; } if (!formData.password) { newErrors.password = 'Şifre gerekli.'; } else if (formData.password.length < 6) { newErrors.password = 'Şifre en az 6 karakter olmalı.'; } return newErrors; }; const handleSubmit = (e) => { e.preventDefault(); const validationErrors = validate(); if (Object.keys(validationErrors).length > 0) { setErrors(validationErrors); console.log('Validasyon hataları:', validationErrors); } else { console.log('Form Gönderildi:', formData); alert(Form Gönderildi: ${JSON.stringify(formData, null, 2)}); // Formu sıfırla setFormData({ username: '', email: '', password: '' }); setErrors({}); } }; return ( ); }Bu snippet, form verilerini tek bir nesne içinde yönetmeyi,
onChangeolayı ile dinamik olarak güncellemeyi vevalidatefonksiyonu ile temel validasyon kurallarını uygulamayı gösterir. Hata mesajları, ilgili alanın altında dinamik olarak gösterilir. Bu yaklaşım, daha karmaşık formlar için kolayca ölçeklendirilebilir.usfo(useStateFormObject) veyaformv(form validation) gibi kısayollar, bu yapıyı hızlıca oluşturmanızı sağlar.Uzman İpucu: Daha karmaşık validasyon senaryoları için,FormikveyaReact Hook Formgibi kütüphaneleri kullanmayı düşünebilirsiniz. Bu kütüphaneler, boilerplate kodunu azaltır ve validasyon mantığını daha verimli bir şekilde yönetmenize yardımcı olur.Gelişmiş React Desenleri ve Kullanışlı Snippet'lar: Portallar, Error Boundary'ler ve Daha Fazlası
React, güçlü ve esnek bir kütüphane olmasının yanı sıra, uygulamanızın belirli senaryolarda daha sağlam, daha performanslı ve daha kullanıcı dostu olmasını sağlayacak gelişmiş desenler ve özellikler sunar. Bu bölümde, React geliştirme deneyiminizi bir üst seviyeye taşıyacak, ileri düzey snippet'lara ve mimarilere odaklanacağız:
React.memoile performans optimizasyonu,Portallarile DOM hiyerarşisi dışına render, veError Boundary'ler ile hata yönetimi.React.memo ile Gereksiz Yeniden Render'ları Engelleyin
Fonksiyonel bileşenler için
React.memo, bir bileşenin prop'ları değişmediği sürece yeniden render edilmesini engelleyen bir üst düzey bileşendir (Higher-Order Component - HOC). Bu, özellikle yoğun hesaplamalar yapan veya sık sık üst bileşenin yeniden render edilmesiyle tetiklenen alt bileşenler için performansı önemli ölçüde artırabilir.React.memo'nun kullanımı oldukça basittir:import React from 'react'; // Normal bir bileşen const MySimpleComponent = ({ title, count }) => { console.log('MySimpleComponent render edildi'); return (); }; // React.memo ile optimize edilmiş bileşen const MemoizedComponent = React.memo(({ title, count }) => { // RM: React.memo console.log('MemoizedComponent render edildi'); return ({title}
Sayaç: {count}
); }); // Kullanım örneği /* function Parent() { const [value, setValue] = useState(0); const [otherState, setOtherState] = useState(false); return ({title}
Sayaç: {count}
); } */Yukarıdaki örnekte,
MemoizedComponent, yalnızcatitleveyacountprop'ları değiştiğinde yeniden render edilir. EğerParentbileşenindeotherStatedeğişirse,MySimpleComponentyeniden render olurken,MemoizedComponentolmaz.rm(React memo) gibi kısayollar, mevcut bir bileşeniReact.memoile sarmalamanızı kolaylaştırır.Portallar ile Bileşenleri DOM Hiyerarşisi Dışına Render Edin
React Portals, bir bileşenin DOM ağacındaki fiziksel konumundan farklı bir yere render edilmesini sağlayan gelişmiş bir özelliktir. Bu, modal pencereler, açılır menüler veya araç ipuçları gibi bileşenler için oldukça kullanışlıdır, çünkü bu elemanların genellikle ana uygulama ağacının üstünde veya dışında olması istenir. Bir portal oluşturmak içinReactDOM.createPortal()kullanılır:import React from 'react'; import ReactDOM from 'react-dom'; // Modal bileşeni function Modal({ children, isOpen, onClose }) { if (!isOpen) return null; return ReactDOM.createPortal( // RPC: React Portal Component, document.getElementById('modal-root') // Bu id'ye sahip DOM elemanı nerede olursa olsun ); } // Kullanım örneği /* function App() { const [isModalOpen, setIsModalOpen] = useState(false); return ({children}setIsModalOpen(false)}>); } */Bu Bir Modal Başlığı
Bu içerik, React ağacının dışında, "modal-root" div'ine render edildi.
// Index.html dosyanızda olmalıBu snippet, bir
ModalbileşenininReactDOM.createPortalkullanarak nasıl ayrı bir DOM elemanına render edileceğini gösterir. Bu, modalınz-indexsorunlarını çözmeye veya overflow özelliklerinden bağımsız hareket etmesini sağlamaya yardımcı olur.rpc(React Portal Component) gibi kısayollar, bir Portal yapısını hızlıca oluşturmanıza olanak tanır.Error Boundary'ler ile Uygulamanızı Hatalara Karşı Koruyun
React uygulamalarında çalışma zamanı hataları kaçınılmazdır. Bir bileşende oluşan hata, tüm uygulamanın çökmesine neden olabilir.
Error Boundary'ler, bileşen ağacının belirli bir kısmındaki JavaScript hatalarını yakalayan, günlüğe kaydeden ve uygulamanın geri kalanını çökertmeden bir geri dönüş UI'ı görüntüleyen React bileşenleridir. Sınıf bileşenleri olarak yazılırlar vestatic getDerivedStateFromError()veyacomponentDidCatch()yaşam döngüsü metotlarını kullanırlar. İşte birError Boundarysnippet'ı:import React, { Component } from 'react'; class ErrorBoundary extends Component { // REB: React Error Boundary constructor(props) { super(props); this.state = { hasError: false, error: null, errorInfo: null }; } static getDerivedStateFromError(error) { // Bir sonraki render'da geri dönüş UI'ını gösterecek şekilde state'i güncelleyin return { hasError: true, error: error }; } componentDidCatch(error, errorInfo) { // Hata bilgilerini bir hata raporlama servisine gönderebilirsiniz console.error("Uncaught error:", error, errorInfo); this.setState({ errorInfo: errorInfo }); } render() { if (this.state.hasError) { // Bir geri dönüş UI'ı gösterebilirsiniz return (); } return this.props.children; } } // Hata tetikleyen örnek bir bileşen function BuggyComponent() { const [count, setCount] = useState(0); const handleClick = () => { setCount(prevCount => prevCount + 1); if (count === 2) { // Hata fırlat throw new Error('Bir hata oluştu!'); } }; return (Bir şeyler ters gitti.
Uygulama beklenmedik bir hata ile karşılaştı.
{this.props.showErrorDetails && this.state.error && ()}Hata Detayları
{this.state.error.toString()}
{this.state.errorInfo && this.state.errorInfo.componentStack}); } // Kullanım örneği /* function App() { return ( ); } */Sayaç: {count}
Bu
ErrorBoundarysnippet'ı, bir hata oluştuğunda durumu nasıl yöneteceğinizi ve bir geri dönüş UI'ı nasıl göstereceğinizi gösterir.reb(React Error Boundary) gibi kısayollar, bu boilerplate sınıf bileşenini hızlıca oluşturmanızı sağlar. Bileşenlerinizi bu şekilde sarmalayarak, uygulamanızın daha dayanıklı olmasını ve küçük hataların tüm kullanıcı deneyimini bozmasını engelleyebilirsiniz.Uzman İpucu: Error Boundary'leri, uygulamanızın mantıksal bölümlerini kapsayacak şekilde yerleştirin. Her bir bileşeni sarmalamanıza gerek yoktur. Genellikle ana layout bileşenleri veya büyük özellik grupları için kullanmak yeterlidir.Test ve Hata Ayıklama Snippet'ları: Sağlam Uygulamalar İnşa Etmek
Herhangi bir yazılım projesinde, test ve hata ayıklama süreçleri, güvenilir ve sürdürülebilir uygulamalar oluşturmak için hayati öneme sahiptir. React uygulamaları da bir istisna değildir. Doğru test stratejileri ve etkili hata ayıklama teknikleri, hem geliştirme süresini kısaltır hem de son kullanıcıya sunulan ürünün kalitesini artırır. Bu bölümde, React bileşenlerinizi test etmek ve olası sorunları gidermek için kullanabileceğiniz faydalı snippet'ları ve yaklaşımları inceleyeceğiz.
React Testing Library ile Bileşenleri Test Etme Snippet'ları
React Testing Library (RTL), React bileşenlerini test etmek için yaygın olarak kullanılan bir kütüphanedir. Felsefesi, bileşenlerinizi kullanıcıların etkileşimde bulunacağı şekilde test etmektir, yani "uygulamanızın kodu değil, uygulamanızın çalıştığı gibi test edin". Bu, erişilebilirlik (accessibility) odaklı ve daha dayanıklı testler yazmanıza olanak tanır. İşte temel bir bileşen testi için snippet:
// MyButton.js import React from 'react'; function MyButton({ onClick, children }) { return ( ); } export default MyButton; // MyButton.test.js import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; // RTL: React Testing Library import '@testing-library/jest-dom/extend-expect'; // Ek Jest matcher'ları için import MyButton from './MyButton'; describe('MyButton', () => { // DESC: describe block it('butona tıklandığında onClick fonksiyonunu çağırır', () => { // IT: it block const handleClick = jest.fn(); // Jest mock fonksiyonu render(Tıkla Bana); const buttonElement = screen.getByText(/Tıkla Bana/i); // Butonu metniyle bul fireEvent.click(buttonElement); // Butona tıklama olayını tetikle expect(handleClick).toHaveBeenCalledTimes(1); // handleClick'in bir kez çağrıldığını kontrol et }); it('doğru metni render eder', () => { render( {}}>Gönder); expect(screen.getByText(/Gönder/i)).toBeInTheDocument(); // Buton metninin dökümanda olup olmadığını kontrol et }); });Bu snippet, bir düğme bileşenini nasıl test edeceğinizi gösterir.
describeveit(veyatest) blokları test senaryolarınızı gruplandırmak için kullanılır.renderfonksiyonu bileşeni sanal DOM'a render ederken,screen.getByTextgibi sorgular kullanıcıların görebileceği elemanları bulmanıza yardımcı olur.fireEvent.clickgibi fonksiyonlar ise kullanıcı etkileşimlerini simüle eder.rtl(React Testing Library) veyartest(React test) gibi kısayollar, yeni bir test dosyası veya temel test bloğu oluşturmanızı hızlandırır.Etkili Hata Ayıklama Teknikleri ve Snippet'ları
Hata ayıklama, bir sorunla karşılaştığınızda onu teşhis etme ve çözme sürecidir. React uygulamalarında hata ayıklama için birçok araç ve teknik mevcuttur:
- React Developer Tools: Tarayıcı eklentisi olarak mevcuttur ve bileşen ağacınızı, prop'larınızı, durumunuzu ve Hook'larınızı incelemenizi sağlar. Genellikle
rdekısayoluyla ilgili paneli açmayı kolaylaştıran bir snippet bulunmaz, ancak bu aracı kullanmaya alışmak en temel hata ayıklama adımıdır.console.log(): En basit ama etkili yöntemdir.useEffectiçinde veya belirli bir fonksiyon çağrıldığında değişkenlerin değerlerini kontrol etmek için kullanılabilir.- Breakpoint'ler: Tarayıcının geliştirici araçlarındaki debugger'ı kullanarak kodunuzda breakpoint'ler ayarlayabilir ve kodunuzun adım adım nasıl çalıştığını izleyebilirsiniz.
- Hata Yakalama (Error Boundary): Yukarıda bahsedildiği gibi, beklenmedik hataları yakalamak ve kullanıcıya dostça bir mesaj göstermek için
Error Boundary'ler kullanın.İşte bir
console.logsnippet'ı veuseEffectiçinde hata ayıklama örneği:import React, { useState, useEffect } from 'react'; function DebuggingComponent() { const [value, setValue] = useState(0); const [data, setData] = useState(null); // Değer değiştiğinde console.log ile izleme useEffect(() => { console.log('Value güncellendi:', value); // CLG: console.log // clgval: console.log('value:', value); // Yaygın snippet formatı }, [value]); // useEffect içinde veri çekme hatası ayıklama useEffect(() => { const fetchData = async () => { try { console.log('Veri çekme başlatıldı...'); const response = await fetch('https://nonexistent-api.com/data'); if (!response.ok) { throw new Error(HTTP error! status: ${response.status}); } const result = await response.json(); setData(result); console.log('Veri başarıyla çekildi:', result); } catch (error) { console.error('Veri çekme hatası:', error); // Hata ayıklama için console.error // Hata durumunda UI'da da gösterilebilir } }; fetchData(); }, []); // Sadece bir kere çalışır return (Hata Ayıklama Bileşeni
Değer: {value}
{data ?{JSON.stringify(data, null, 2)}:
Veri yok veya hata oluştu.
}
);
}
Bu örnek,
console.logveconsole.errorkullanarak durum değişikliklerini ve yan etki operasyonlarını nasıl izleyeceğinizi gösterir.clg(console log),clgvar(console log variable) gibi kısayollar, bu log ifadelerini hızlıca kodunuza eklemenizi sağlar. Etkili bir hata ayıklama süreci, sorunları hızla tespit etmenize ve gidermenize yardımcı olur, böylece geliştirme akışınız kesintiye uğramaz.Uzman İpucu: Production ortamındaconsole.log'ları temizlemeyi unutmayın! Build araçları (örneğin Webpack, Rollup) için eklentilerle veya manuel olarak bu log'ları otomatik olarak kaldırabilirsiniz. Bu, hem uygulamanızın performansını artırır hem de hassas bilgilerin konsola sızmasını engeller.Sonuç: React Geliştirme Sürecinizi Hızlandırın ve İyileştirin
Bu makale boyunca, React geliştirme deneyiminizi önemli ölçüde hızlandıracak ve kod kalitenizi artıracak en faydalı snippet'ları derinlemesine inceledik. Temel Hook'lardan (
useState,useEffect) başlayarak, performans optimizasyonlarına (useMemo,useCallback), veri yönetimi çözümlerine (Context API), form işleme ve validasyona, ileri düzey desenlere (Portals,Error Boundary) ve son olarak da test ve hata ayıklama tekniklerine kadar geniş bir yelpazeyi kapsayan pratik kod örnekleri ve vaka analizleri sunduk.Snippet'lar, sadece tekrarlayan kod yazma yükünü azaltmakla kalmaz, aynı zamanda projelerinizde tutarlı bir kodlama stili benimsemenizi ve yaygın desenleri daha hızlı uygulamanızı sağlar. Bu, özellikle ekip içinde çalışırken veya büyük ölçekli uygulamalar geliştirirken paha biçilmez bir avantaj sunar. Geliştirme ortamınızda (örneğin VS Code) uygun snippet uzantılarını kullanarak bu kısayolların gücünü tam olarak açığa çıkarabilirsiniz. Böylece, manuel yazım hatalarını en aza indirirken, daha karmaşık mantık ve özellik geliştirmeye odaklanmak için daha fazla zamanınız kalır.
Unutmayın ki bu makalede bahsedilen 50 snippet, React ekosistemindeki zengin araçların sadece küçük bir bölümünü temsil etmektedir. Kendi çalışma alışkanlıklarınıza ve projelerinizin özel ihtiyaçlarına göre ek snippet'lar keşfetmek veya kendi özel snippet'larınızı oluşturmak, verimliliğinizi daha da artıracaktır. React topluluğu sürekli büyüyor ve yeni en iyi pratikler ortaya çıkıyor. Bu nedenle, öğrenmeye ve adapte olmaya devam etmek, modern web geliştiricileri için anahtardır. Sunduğumuz bu araçlar ve yaklaşımlar sayesinde, daha temiz, daha hızlı ve daha sağlam React uygulamaları inşa etme yolculuğunuzda önemli bir adım atmış olacaksınız.
Sıkça Sorulan Sorular
- React snippet'ları nedir ve neden kullanmalıyım?
- React snippet'ları, sık kullanılan React kod kalıplarını (örneğin, Hook'lar, bileşen yapıları) otomatik olarak oluşturan kısa kod şablonlarıdır. Geliştirme hızınızı artırır, yazım hatalarını azaltır ve kod tutarlılığını sağlar.
- Hangi IDE'lerde React snippet'larını kullanabilirim?
- Başta VS Code olmak üzere, Sublime Text, WebStorm gibi popüler IDE'ler için birçok React snippet uzantısı mevcuttur. VS Code için "ES7 React/Redux/GraphQL/React-Native snippets" uzantısı en popüler olanlardan biridir.
- Kendi özel React snippet'larımı oluşturabilir miyim?
- Evet, çoğu modern IDE, kendi özel snippet'larınızı tanımlamanıza olanak tanır. Bu, sıkça kullandığınız ancak hazır snippet'larda bulamadığınız kod kalıplarını kişiselleştirmenizi sağlar.
- useMemo ve useCallback ne zaman kullanılmalı?
- Her ikisi de performans optimizasyonu için kullanılır.
useMemo, pahalı hesaplamaların sonucunu ön belleğe almak için kullanılırken,useCallback, bir fonksiyon referansını ön belleğe almak için kullanılır. ÖzellikleReact.memoile optimize edilmiş alt bileşenlere prop olarak fonksiyon geçiyorsanız, gereksiz yeniden render'ları önlemek içinuseCallbackkullanmak faydalıdır. - Prop drilling sorununu Context API dışında nasıl çözebilirim?
- Prop drilling, genellikle
Context APIile çözülür. Daha karmaşık global durumlar için Redux, Zustand, Recoil gibi durum yönetim kütüphanelerini kullanabilirsiniz. Ayrıca, "render props" desenleri veya custom hook'lar da prop'ların derinlemesini engellemeye yardımcı olabilir.
