React custom hook'lar, bileşenler arasında state mantığını yeniden kullanılabilir hale getirmenin temel yoludur. Peki, bu güçlü özelliği kullanırken nelere dikkat etmeli ve hangi hatalardan kaçınmalısınız? İşte React geliştiricilerinin custom hook yazarken karşılaştığı en yaygın sorunlar ve çözümleri.
Custom Hook Nedir ve Ne Zaman Kullanılmalıdır?
Custom hook, React'in useState, useEffect, useRef gibi temel hook'larını kullanarak oluşturduğunuz ve "use" ile başlayan bir JavaScript fonksiyonudur. Amacı, birden çok bileşende tekrarlanan stateful mantığı soyutlamaktır. Örneğin, bir form girişi, pencere boyutunu izleme veya veri çekme işlemleri custom hook yapmak için uygun adaylardır.
Custom hook kullanmanız gereken durumlar:
- İki veya daha fazla bileşende aynı state mantığı tekrar ediyorsa
- Bir efekti (örneğin, pencere boyut değişikliği dinleme) merkezi hale getirmek istiyorsanız
- Karmaşık state işlemlerini basit bir API ile sarmalamak istiyorsanız
Ancak, her tekrarlanan kod için custom hook yazmak zorunda değilsiniz. Eğer mantık stateful değilse veya yalnızca bir bileşen tarafından kullanılıyorsa, doğrudan fonksiyon yazmak daha temiz olabilir.
En İyi Uygulamalar
1. Hook'ları Küçük ve Odaklı Tutun
Bir custom hook tek bir sorumluluğa sahip olmalıdır. Örneğin, useWindowSize yalnızca pencere boyutunu döndürür; useLocalStorage yerel depolama ile ilgilenir. Eğer hook'unuz birden çok iş yapıyorsa, onu daha küçük hook'lara bölün.
2. Geri Dönen Değerleri Sabit Referanslarla Döndürün
Özellikle state ve dispatch fonksiyonları gibi değerleri her render'da yeniden oluşturmak gereksiz yeniden render'lara yol açar. useMemo ve useCallback kullanarak referansları sabitleyin. Örneğin:
function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
const toggle = useCallback(() => setValue(v => !v), []);
return [value, toggle];
}
3. Efektleri Doğru Temizleyin
Custom hook içinde abonelik veya zamanlayıcı gibi yan etkiler yarattığınızda, temizleme işlevini useEffect'in dönüş değeri olarak sağlayın. Aksi takdirde bellek sızıntıları ve hatalı davranışlar ortaya çıkar.
4. Esnek Bir API Tasarımı
Hook'unuzun kullanıcısına esneklik sağlayın. Örneğin, bir veri çekme hook'u başlangıçta yüklenecek fonksiyonu parametre olarak almalıdır. Ayrıca opsiyonel konfigürasyon parametreleri (cache süresi, hata işleme stratejisi) ekleyerek farklı kullanım senaryolarına uygun hale getirin.
Sık Yapılan Hatalar
1. Hook İçinde Başka Hook'ları Koşullu Olarak Çağırmak
React'in kurallarına göre hook'lar her render'da aynı sırada çalışmalıdır. Custom hook içinde bir hook'u if-else bloklarına sarmak bu kuralı ihlal eder. Bunun yerine, koşullu mantığı hook'un içindeki diğer mekanizmalarla (örneğin, useReducer'a farklı initial değerler vererek) yönetin.
2. State Yerine Yanlış Veri Yapısı Kullanmak
Özellikle form verileri gibi alanlarda state'in değişmez bir nesne (immutable object) olarak yönetilmesi gerekir. useState'e doğrudan mutate etmek yerine yeni bir obje oluşturarak güncelleme yapın. Bu hatayı önlemek için useReducer daha uygun olabilir.
3. Gereğinden Fazla Render Tetiklemek
Custom hook'ta state her güncellendiğinde, bu hook'u kullanan tüm bileşenler yeniden render edilir. Eğer hook sık sık değişen bir state (örneğin fare konumu) döndürüyorsa, throttle veya debounce uygulayarak render sayısını azaltın. JavaScript'te Debounce ve Throttle: Pratik İpuçları ve Kontrol Listesi yazımızdaki teknikleri burada kullanabilirsiniz.
4. State'in Bağımlılıklarını Doğru Belirtmemek
Custom hook'un dönüş değerlerinden biri başka bir state'e bağlıysa, bu bağımlılıkları useMemo veya useEffect bağımlılık dizisinde belirtmelisiniz. Unutulan bağımlılıklar, bayat (stale) değerlere yol açar.
Gerçek Dünyadan Örnek: useAsync Hook'u
Aşağıda, asenkron bir işlemi (örneğin API çağrısı) yöneten basit bir custom hook bulunuyor:
import { useState, useEffect, useCallback } from 'react';
export function useAsync(asyncFunction, immediate = true) {
const [status, setStatus] = useState('idle');
const [value, setValue] = useState(null);
const [error, setError] = useState(null);
const execute = useCallback(() => {
setStatus('pending');
setValue(null);
setError(null);
return asyncFunction()
.then(response => {
setValue(response);
setStatus('success');
})
.catch(err => {
setError(err);
setStatus('error');
});
}, [asyncFunction]);
useEffect(() => {
if (immediate) {
execute();
}
}, [execute, immediate]);
return { execute, status, value, error };
}
Bu hook, veri çekme işlemlerinde kullanışlıdır. Ancak daha karmaşık senaryolar (önbellekleme, yeniden deneme) için React Query vs SWR karşılaştırmasına göz atın.
Custom Hook'lar ve State Yönetimi
Custom hook'lar, state mantığını paylaşmada güçlü bir araçtır, ancak global state yönetimi için yeterli olmayabilir. Uygulama genelinde kullanılacak state'ler (örneğin kullanıcı oturumu) için Context API, Redux, Zustand gibi yöntemlere ihtiyaç duyarsınız. React State Management Karşılaştırması yazımızda bu yaklaşımları detaylıca ele aldık.
Özet
- Custom hook'lar, state mantığını soyutlamak için idealdir, ancak aşırı kullanımdan kaçının.
- Hook'ları küçük, odaklı ve esnek tutun.
- Performans için referansları sabitleyin ve gereksiz render'ları önleyin.
- Bağımlılıkları ve temizleme işlemlerini doğru yönetin.
- Global state ihtiyacı durumunda bir state yönetim kütüphanesi değerlendirin.
Custom hook yazarken dikkat edilmesi gerekenler listesi ve sık yapılan hatalar tablosu:
| Durum | Yanlış Yaklaşım | Doğru Yaklaşım |
|---|---|---|
| Koşullu hook çağırma | if (value) { useHook() } | Her zaman tüm hook'ları çağır, mantığı içeride yönet |
| State'i mutate etme | state.key = yeniDeger | setState({ ...state, key: yeniDeger }) |
| Sık güncelleme | Anında güncelle | Debounce veya throttle uygula |
| Eksik bağımlılık | [] boş dizi | Tüm kullanılan değişkenleri ekle |
Bu rehberde anlatılanları projelerinizde uygulayarak daha temiz, yeniden kullanılabilir ve bakımı kolay React bileşenleri yazabilirsiniz.
Sık Sorulan Sorular
Custom hook yazarken en sık yapılan hata nedir?
En sık yapılan hata, hook içinde başka hook'ları koşullu olarak çağırmaktır. Bu, React'in hook kurallarını ihlal eder ve uygulamanın hatalı çalışmasına yol açar.
Custom hook ne zaman kullanılmalıdır?
Birden çok bileşende aynı state mantığı tekrar ediyorsa veya bir efekti merkezi hale getirmek istiyorsanız custom hook kullanmalısınız. Ancak yalnızca bir bileşende kullanılacaksa doğrudan bileşen içinde yazmak daha temiz olabilir.
Custom hook içinde useEffect temizleme işlemi nasıl yapılır?
useEffect'in callback fonksiyonunda dönüş değeri olarak bir temizleme fonksiyonu sağlayın. Örneğin, bir abonelik varsa abonelikten çıkma işlemini bu fonksiyonda yapmalısınız.
Custom hook performansı nasıl optimize edilir?
useMemo ve useCallback kullanarak değerlerin referanslarını sabitleyin. Ayrıca sık güncellenen durumlar için debounce veya throttle uygulayarak gereksiz render'ları önleyin.
Custom hook yerine Context API veya Redux kullanmalı mıyım?
Custom hook'lar bileşenler arasında mantık paylaşımı için idealdir, ancak uygulama genelinde global state yönetimi gerekiyorsa Context API, Redux Toolkit veya Zustand gibi state yönetim kütüphanelerini tercih edin.






