ViraStack
  • Academy
  • About
  • Support
HomeSourcesContribute
ViraStack

A frontend ecosystem: free guides, project templates, AI rules, and form components.

Products

  • ViraStack Start
  • ViraStack AI
  • ViraStack Mask
  • ViraStack Password
  • ViraStack Guide

Explore

  • Academy
  • About
  • Brand
  • Support

© 2026 ViraStack.

Open source · MIT

React

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

  1. Yalnızca en üst seviyede çağırın. if, döngü, iç içe fonksiyon ya da erken return'den sonra çağırmayın.

  2. 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. useMount ya da useEffectOnce gibi yaşam döngüsü hook'ları yazmayın; useOnlineStatus, useProduct(id), useDebouncedValue gibi ne işe yaradığını söyleyen isimler verin.4

  • Arayü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.5

  • Effect'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ğırmayan useFormatPrice gibi fonksiyonlar gereksizdir. Hook çağırmıyorsa adı formatPrice olmalı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; query ve debouncedQuery'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'tan useChatRoom'a adım adım hook çıkarma.4

  • Yazı: 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

  • 1DocsReact: Rules of Hooks

    Hook'ları yalnızca üst seviyede ve React fonksiyonlarından çağırma kuralı.

  • 2ArticleDan Abramov

    : — 13 Aralık 2018. Çağrılma sırasına dayanan tasarım ve alternatiflerinin sorunları.

  • 3DocsReact: use

    Koşul içinde çağrılabilen `use`.

  • 4DocsReact: Reusing Logic with Custom Hooks

    Mantığı paylaşmak, state'i paylaşmamak, isimlendirme ve yaşam döngüsü hook'larından kaçınma.

  • 5ArticleTkDodo

    : — 23 Ocak 2021. Effect'leri isimli hook'lara taşımak ve küçük arayüz.

  • 6DocsReact: useSyncExternalStore

    Dış store'a abone olmak, `subscribe`'ı dışarıda tanımlamak ve sunucu değeri.

  • 7DocsReact: You Might Not Need an Effect, Subscribing to an external store

    Effect + state yerine `useSyncExternalStore` önerisi.

  • 8ArticleTkDodo

    : — 21 Şubat 2024. `getServerSnapshot` ile sunucu ve istemci değerini ayırmak.

Edit this page

Last updated: October 21, 2026

Previous step07. ContextNext step09. Suspense ve hata sınırları