08 / 12
Custom hook
Hook kuralları, tekrar eden mantığı hook'a taşımak, iyi bir hook API'si ve useSyncExternalStore.
Hook Kuralları
use ile başlayan her fonksiyon bir hook'tur. İki kural vardır:1
Yalnızca en üst seviyede çağırın.
if, döngü, iç içe fonksiyon ya da erkenreturn'den sonra çağırmayın.Yalnızca React fonksiyonlarından çağırın. Component'lerden ya da başka hook'lardan; sıradan bir fonksiyondan değil.
Neden? React hook'ları isimle değil çağrılma sırasıyla tanır. Birinci useState her render'da birinci olmalıdır; bir koşul sırayı değiştirirse state'ler karışır. Dan Abramov bu tasarımın arkasındaki ödünleşimleri uzun bir yazıda anlatıyor.2 İstisna use'dur: koşul içinde çağrılabilir.3 rules-of-hooks lint kuralı ihlalleri yakalar.
Custom Hook Nedir
Custom hook, içinde başka hook'lar çağıran ve adı use ile başlayan sıradan bir fonksiyondur. Component'lerdeki tekrar eden mantığı paylaşır.4
import { useEffect, useState } from "react";
export function useDebouncedValue<T>(value: T, delay = 300) {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debounced;
}function ProductSearch() {
const [query, setQuery] = useState("");
const debouncedQuery = useDebouncedValue(query);
// debouncedQuery ile arama yap
}Warning
Hook mantığı paylaşır, state'i paylaşmaz. useDebouncedValue'yu iki component'te çağırırsanız iki ayrı state oluşur. Ortak state gerekiyorsa state'i ebeveyne taşıyın ya da Context kullanın.4
İyi Bir Hook
Amacı somut olsun.
useMountya dauseEffectOncegibi yaşam döngüsü hook'ları yazmayın;useOnlineStatus,useProduct(id),useDebouncedValuegibi ne işe yaradığını söyleyen isimler verin.4Arayüzü küçük olsun. TkDodo'nun örneğinde başlığı yalnızca
document.title'da gösteren bir hook, değeri hiç dışarı açmaz; sadece setter'ı döndürür. Hook'a ait olan her şey içinde kalır.5Effect'leri sarın. Component'teki her Effect, adı olan bir hook'a taşınmaya adaydır. Component *"nasıl"*ı değil *"ne"*yi anlatır.45
Gereksiz yere çıkarmayın. Tek bir
useState'i saran hook ya da hiç hook çağırmayanuseFormatPricegibi fonksiyonlar gereksizdir. Hook çağırmıyorsa adıformatPriceolmalıdır.4
Hook'u nereye koyacağınız ve ne zaman ortak klasöre taşıyacağınız Component ve Kod Organizasyonu rehberinde.
Dış Bir Kaynağa Abone Olmak
Tarayıcının bağlantı durumu, localStorage, ekran genişliği ya da bir store gibi React dışında tutulan veriyi okumak için Effect + useState yerine useSyncExternalStore kullanın. React dokümanı bu iş için elle yazılmış Effect yerine bu hook'u önerir.67
import { useSyncExternalStore } from "react";
function subscribe(callback: () => void) {
window.addEventListener("online", callback);
window.addEventListener("offline", callback);
return () => {
window.removeEventListener("online", callback);
window.removeEventListener("offline", callback);
};
}
export function useOnlineStatus() {
return useSyncExternalStore(
subscribe,
() => navigator.onLine, // tarayıcıda değer
() => true, // sunucuda değer
);
}subscribe component dışında tanımlıdır; her render'da yeni fonksiyon verirseniz React yeniden abone olur.6 Üçüncü argüman, sunucuda render ederken kullanılacak değerdir. TkDodo, bu argümanın SSR'da hydration uyuşmazlığını önlemek için de kullanılabileceğini gösterir.8
function CheckoutButton() {
const isOnline = useOnlineStatus();
return <button disabled={!isOnline}>{isOnline ? "Ödemeye geç" : "Bağlantı yok"}</button>;
}Hook'u Test Etmek
Custom hook'u kullanan component üzerinden test etmek çoğu zaman yeterlidir. Hook tek başına bir kütüphane gibi kullanılıyorsa React Testing Library'nin renderHook'u ile test edilir; Provider ve Hook dersi anlatıyor.
Kendin Dene
useDebouncedValue'yu bir arama kutusunda kullanın;queryvedebouncedQuery'yi yan yana ekrana basıp farkı görün.useOnlineStatus'u iki farklı component'te kullanın. DevTools'ta Network sekmesinden "Offline" seçin; ikisi de güncelleniyor mu?subscribe'ı component'in içine taşıyın ve React DevTools Profiler'da ne değiştiğine bakın.Projenizde bir component'teki iki Effect'i, adı ne yaptığını söyleyen iki hook'a taşıyın.
Detaylı Öğrenmek İçin
Resmi doküman: "Reusing Logic with Custom Hooks";
useOnlineStatus'tanuseChatRoom'a adım adım hook çıkarma.4Yazı: Dan Abramov'un "Why Do Hooks Rely on Call Order?" yazısı; hook kurallarının nedenini alternatif tasarımlarla karşılaştırır.2
Yazı: TkDodo'nun "Simplifying useEffect" yazısındaki custom hook bölümü.5
Kaynaklar
Hook'ları yalnızca üst seviyede ve React fonksiyonlarından çağırma kuralı.
: — 13 Aralık 2018. Çağrılma sırasına dayanan tasarım ve alternatiflerinin sorunları.
Koşul içinde çağrılabilen `use`.
Mantığı paylaşmak, state'i paylaşmamak, isimlendirme ve yaşam döngüsü hook'larından kaçınma.
: — 23 Ocak 2021. Effect'leri isimli hook'lara taşımak ve küçük arayüz.
Dış store'a abone olmak, `subscribe`'ı dışarıda tanımlamak ve sunucu değeri.
Effect + state yerine `useSyncExternalStore` önerisi.
: — 21 Şubat 2024. `getServerSnapshot` ile sunucu ve istemci değerini ayırmak.
Last updated: October 21, 2026
