React hooks, geliştiricilerin kullanıcı arayüzleri oluşturma şeklini temelden değiştirdi ve durumu yan etkilerle yönetmek için daha sezgisel bir yol sunuyor. Ancak useState ve useEffect temellerini öğrendikten sonra gerçek güç, gelişmiş desenleri anlamakta yatıyor. Bu teknikler, yeniden kullanılabilir mantık oluşturmanıza, performansı optimize etmenize ve karmaşık uygulamalarda temiz bir mimari korumanıza olanak tanır. Bu yazıda, React becerilerinizi orta seviyeden uzman seviyesine taşıyacak sofistike hook desenlerini keşfedeceğiz.
Mantık Ayıklama İçin Özel Hooks Gücü
Özel hooks, yalnızca prop drilling'den kaçınmanın bir yolu değildir; bunlar, karmaşık iş mantığını UI bileşenlerinden ayıklamanın birincil mekanizmasıdır. Özel hooks'un use ile başlaması kuralına uyarak, React'in linter'ı otomatik olarak hooks kurallarını uygulayabilir. Bu, API çağrıları veya form işleme gibi durumlu mantığı kapsüllemenize ve bileşenlerinizi tamamen sunumsal hale getirmenize olanak tanır.
Otomatik yeniden deneme mantığıyla veri çekmeniz gereken bir senaryoyu düşünün. Bu mantığı birden fazla bileşene yaymak yerine, bir useFetchWithRetry hook'u oluşturabilirsiniz. Bu, kod yeniden kullanımını teşvik eder ve bileşen ağacından bağımsız olarak hook'u test edebildiğiniz için test etmeyi önemli ölçüde kolaylaştırır.
function useFetchWithRetry(url, retries = 3) {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
let attempt = 0;
const fetchData = async () => {
try {
setIsLoading(true);
const response = await fetch(url);
if (!response.ok) throw new Error(response.statusText);
const json = await response.json();
setData(json);
setError(null);
} catch (err) {
attempt++;
if (attempt < retries) {
setTimeout(fetchData, 1000 * attempt);
} else {
setError(err);
}
} finally {
setIsLoading(false);
}
};
fetchData();
}, [url, retries]);
return { data, error, isLoading };
}
useMemo ve useCallback ile Performans Optimizasyonu
React geliştirmede en yaygın yanlış anlaşılmalardan biri, her durum güncellemesinin tüm alt bileşenlerin tam bir yeniden render edilmesini tetiklemesidir. React hızlı olsa da, gereksiz render'lar büyük uygulamalarda fark edilebilir gecikmelere yol açabilir. useMemo ve useCallback hook'ları, bu gereksiz hesaplamaları önlemek için temel araçlardır.
useCallback, bağımlılıklarından biri değişmediği sürece değişmeyen bir callback'in memoize edilmiş bir sürümünü döndürür. Bu, React.memo gibi referans eşitliği kontrollerine dayanan optimize edilmiş alt bileşenlere callback'ler geçirirken özellikle kullanışlıdır. Benzer şekilde, useMemo pahalı hesaplamaları memoize eder. Ancak bunları az kullanmalısınız. Aşırı optimizasyon, kodun okunmasını ve hata ayıklamasını zorlaştırabilir. Memoization eklemeden önce gerçek darboğazları belirlemek için uygulamanızı her zaman profilleyin.
useReducer ile Gelişmiş Durum Yönetimi
useState basit durumlar için mükemmel olsa da, birden fazla alt değeri içeren veya bir önceki duruma bağlı olan karmaşık durum mantığı useReducer için daha uygundur. Bu desen, Redux'tan ilham alarak durum geçişlerini öngörülebilir bir şekilde yönetmenize olanak tanır. Birden fazla değeri içeren karmaşık durum mantığınız olduğunda veya bir sonraki durum bir önceki duruma bağlı olduğunda özellikle etkilidir.
useReducer kullanmak, bileşen mantığınızı daha anlaşılır ve test edilebilir hale getirir. Payload'larla eylemler gönderebilir ve reducer fonksiyonu durumu güncellemenin saf mantığını işler. Bu sorumluluk ayrımı, özellikle durum karmaşıklığı zamanla arttığından büyük ölçekli uygulamalarda daha sürdürülebilir kod tabanlarına yol açar.
const initialState = { count: 0, step: 1 };
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { ...state, count: state.count + state.step };
case 'setStep':
return { ...state, step: action.payload };
default:
throw new Error();
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'increment' })}>
Add
</button>
</div>
);
}
Sonuç
Gelişmiş React hooks'ları ustalaşmak, React'in yan etkileri ve durumu nasıl yönettiğine dair derin bir anlayış gerektirir. Mantık ayıklama için özel hooks'tan yararlanarak, memoization ile render'ları optimize ederek ve karmaşık durum için useReducer kullanarak ölçeklenebilir ve performanslı uygulamalar oluşturabilirsiniz. Bu araçların sihirli değnekler olmadığını unutmayın; belirli sorunları çözmek için özenle uygulanmalıdır. Gelişmeye devam ettikçe, React ekosisteminin tam potansiyelinden yararlanan temiz, test edilebilir ve sürdürülebilir kod yazmaya odaklanın.