Özel hook (custom hook), adı use ile başlayan ve başka hook'ları çağıran bir fonksiyondur. İki bileşenin aynı state'li mantığa ihtiyacı olduğunda bir tane yazarsın: useState ve useEffect çağrılarını fonksiyona taşı, bileşenin ihtiyaç duyduğunu döndür ve her bileşenden onu çağır.
İki spoiler da useToggle'ı çağırır ve birini açmak diğerini kapalı bırakır. Her çağrı kendi useState'ini çalıştırır, bu yüzden her bileşen kendi değerini alır. Özel bir hook state'i değil, mantığı paylaşır.
Bir tane yazmanın kuralları
- Ad
useve bir büyük harfle başlar:useToggle,useOnlineStatus. Hook'lar için lint kuralı, hook çağrılarını bulup kontrol etmek için öneki kullanır. - En az bir hook çağırır. Hiç hook çağırmayan bir yardımcı sıradan bir fonksiyondur; ona
useFormatDatedeğilformatDateadını ver, böylece koşulların içi dahil her yerde çağrılabilir. - Hook kurallarına uyar: hook'ları kendi en üst düzeyinde çağır ve onu yalnızca bileşenlerden ya da başka özel hook'lardan çağır.
- İşe yarayan her şeyi döndürür. Bir dizi (
[on, toggle]) çağıranlar değerleri yeniden adlandırdığında kullanışlıdır; bir nesne ({ data, loading, error }) üç ya da daha fazlası için daha iyi okunur.
useLocalStorage: yeniden yüklemeden sağ çıkan state
useState yeniden yüklemede her şeyi unutur. Bu hook başlangıç değerini localStorage'dan okur ve her değişikliği geri yazar.
Önizleme, tarayıcının localStorage'ı engellediği izole bir çerçevede çalışır, bu yüzden burada Console'da uyarıyı görürsün ve hook düz state'e geri döner. Normal bir sayfada ad yeniden yüklemeden sağ çıkar. try/catch yalnızca bu önizleme için değil: gizli tarama modları, engellenmiş çerezler ve dolu bir kota, gerçek uygulamalarda da depolamanın hata fırlatmasına yol açar. useState'e bir fonksiyon aktarmak depolamanın bir kez, ilk render'da okunması demektir.
useDebounce: kullanıcı yazmayı bırakana kadar bekle
Bir arama kutusu her tuş vuruşunda istek göndermemelidir. useDebounce, belirli bir gecikme boyunca değişmeyi bıraktıktan sonra güncellenen bir değer kopyası döndürür.
Hızlıca bir sözcük yaz: Typed her tuşu takip eder, Debounced sen durduktan yarım saniye sonra yetişir ve Console bir arama kaydeder. Her tuş vuruşu value'yu değiştirir, bu yüzden React yeni bir zamanlayıcı başlatmadan önce temizlemeyi (clearTimeout) çalıştırır. 500'ü 0 yap; her tuş vuruşu kendi aramasını kaydeder.
useWindowWidth: temizlemeyle abone olmak
Tarayıcıyı dinleyen bir hook, bileşen gittiğinde dinleyicisini kaldırmalıdır; yoksa her mount arkasında bir tane bırakır.
Tarayıcı penceresini yeniden boyutlandır; sayı takip eder. Düğmeye tıkla; Console dinleyicinin kaldırıldığını gösterir. Efektten return'ü sil, sonra birkaç kez mount ve unmount et: her seferinde bir added satırı alırsın ve hiç removed yoktur, yani eski dinleyiciler birikir. Bunun gibi tarayıcı değerleri için useSyncExternalStore, React'in bu iş için yaptığı hook'tur ve bir özel hook'un içinde çağrılması iyi bir şeydir.
Mantık paylaşılır, state paylaşılmaz
Aynı hook'u çağıran iki bileşen, içindeki her şeyin iki ayrı kopyasını alır. Bu, bir hook'un global bir değişken gibi çalışmasını bekleyenleri şaşırtır.
Herhangi bir düğmeye tıkla; yalnızca o sayaç ilerler. İkisinin de aynı sayıyı göstermesi gerekiyorsa state'i App'e taşı ve aşağı aktar ya da bir context'e koy. Bir özel hook kolaylık için bu paylaşılan state'i sarabilir (bir CartContext'i okuyan useCart()), ama paylaşım hook'tan değil context'ten gelir.
Ne zaman özel hook yazılmalı
Aynı hook çağrıları grubu iki bileşende göründüğünde ya da bir bileşenin efekt mantığı bir adın onu daha iyi açıklayacağı kadar uzun olduğunda bir hook çıkar (useOnlineStatus(), yirmi satır dinleyiciden daha iyi okunur). Tek bir useState çağrısını sadece yeniden adlandırmak için bir hook'a sarma ve props'tan state ayarlamak için yalnızca useEffect çağıran hook'lar yazma; bunun yerine o değeri render sırasında hesapla.
Sıkça Sorulan Sorular
React'te özel hook (custom hook) nedir?
Adı use ile başlayan ve bir ya da daha fazla başka hook'u çağıran bir JavaScript fonksiyonudur. State'li mantığı (state, efektler, ref'ler) paketler, böylece her bileşen fonksiyonu çağırarak onu yeniden kullanabilir.
Özel hook'lar bileşenler arasında state paylaşır mı?
Hayır. Bir özel hook'a yapılan her çağrı kendi useState ve useEffect çağrılarını çalıştırır, bu yüzden her bileşen bağımsız state alır. Aynı değeri bileşenler arasında paylaşmak için state'i yukarı taşı ya da bir context'e veya dış bir store'a koy.
Bir özel hook'un adı neden use ile başlamalı?
Ad, React'in lint kurallarına ve diğer geliştiricilere fonksiyonun hook çağırdığını söyler; böylece hook kuralları ona uygulanır: onu en üst düzeyde çağır, asla bir koşul ya da döngü içinde değil. Önek olmadan linter içindeki çağrıları kontrol edemez.
Bir özel hook JSX döndürebilir mi?
Her şeyi döndürebilir, ama JSX döndürüyorsa genellikle bir bileşen olarak yazılması daha iyidir. Özel hook'lar tipik olarak değerler ve fonksiyonlar döndürür; bir dizi ([value, toggle]) ya da bir nesne ({ data, error, loading }) olarak.
Bir özel hook'u useEffect ya da bir olay işleyicisi içinde çağırabilir miyim?
Hayır. Bir özel hook yine de bir hook'tur, bu yüzden hook kurallarına uyar: onu bir bileşenin ya da başka bir özel hook'un en üst düzeyinde çağır.