React Hooks ile En İyi Uygulamalar
Yayınlanan: 2022-03-10 React Hooks, bir class
bileşeni yazmadan durum ve diğer React özelliklerini kullanmanıza izin veren React 16.8'deki yeni bir eklentidir. Başka bir deyişle, Kancalar, işlev bileşenlerinden React durumu ve yaşam döngüsü özelliklerine "bağlanmanıza" izin veren işlevlerdir. ( class
bileşenleri içinde çalışmazlar.)
React, useState
gibi birkaç yerleşik Kanca sağlar. Farklı bileşenler arasında durum bilgisi olan davranışı yeniden kullanmak için kendi Kancalarınızı da oluşturabilirsiniz. Aşağıdaki örnek, durumu useState()
kancası kullanılarak yönetilen bir sayacı göstermektedir. Düğmeye her tıkladığınızda, count
değerini 1
ile güncellemek için setCount()
işlevini kullanırız.
Bu örnek, 0
değerine sahip bir sayaç oluşturur. Düğmeye tıkladığınızda, değeri 1
artırır. Bileşenin başlangıç değeri useState
kullanılarak tanımlanır.
const [count, setCount] = useState(0)
Gördüğünüz gibi, bunu 0
olarak ayarladık. Ardından, değeri artırmak istediğimizde setCount
çağırmak için onClick()
yöntemini kullanırız.
<button onClick={() => setCount(count + 1)}> Click me </button>
React Hooks'un piyasaya sürülmesinden önce, bir class
bileşenini kullanmamız gerekeceğinden, bu örnek daha fazla kod satırı kullanırdı.
Tepki Kancalarının Kuralları
En iyi uygulamalara derinlemesine dalmadan önce, bu makalede sunulan uygulamaların temel kavramlarından bazıları olan React Hooks kurallarını anlamamız gerekiyor.
React Hook'lar JavaScript işlevleridir, ancak bunları kullanırken iki kurala uymanız gerekir.
- En üst düzeyde Çağrı Kancaları;
- Hook'ları yalnızca React bileşenlerinden çağırın.
Not : Bu iki kural, JavaScript'in kendisinin bir parçası olmak yerine React Hooks'ta tanıtıldı.
Bu kurallara daha ayrıntılı olarak bakalım.
En Üst Düzeyde Çağrı Kancaları
Döngüler, koşullar veya iç içe işlevler içindeki Hook'ları çağırmayın. Kancaları her zaman React işlevinizin en üst düzeyinde kullanın. Bu kuralı izleyerek, bir bileşen her işlendiğinde Hook'ların aynı sırada çağrılmasını sağlarsınız. React'in çoklu useState
ve useEffect
çağrıları arasında Hook'ların durumunu doğru bir şekilde korumasını sağlayan şey budur.
İki durumu olacak bir Form
bileşeni yapalım:
-
accountName
-
accountDetail
Bu durumlar varsayılan değerlere sahip olacak, durumu tarayıcımızın yerel depolamasında veya belgemizin başlığında sürdürmek için useEffect
kancasını kullanacağız.
Şimdi, bu bileşen, birden fazla useState
ve useEffect
çağrısı arasında aynı kalırsa, durumunu başarılı bir şekilde yönetmek için olabilir.
function Form() { // 1. Use the accountName state variable const [accountName, setAccountName] = useState('David'); // 2. Use an effect for persisting the form useEffect(function persistForm() { localStorage.setItem('formData', accountName); }); // 3. Use the accountDetail state variable const [accountDetail, setAccountDetail] = useState('Active'); // 4. Use an effect for updating the title useEffect(function updateStatus() { document.title = accountName + ' ' + accountDetail; }); // ... }
Kancalarımızın sırası değişirse (bu, döngüler veya koşullu olarak çağrıldıklarında mümkün olabilir), React bileşenimizin durumunu nasıl koruyacağını bulmakta zorlanır.
// ------------ useState('David') // 1. Initialize the accountName state variable with 'David' useEffect(persistForm) // 2. Add an effect for persisting the form useState('Active') // 3. Initialize the accountdetail state variable with 'Active' useEffect(updateStatus) // 4. Add an effect for updating the status // ------------- // Second render // ------------- useState('David') // 1. Read the accountName state variable (argument is ignored) useEffect(persistForm) // 2. Replace the effect for persisting the form useState('Active') // 3. Read the accountDetail state variable (argument is ignored) useEffect(updateStatus) // 4. Replace the effect for updating the status // ...
Bu, React'in kancalarımızı çağırmak için izlediği sıradır. Sıra aynı kaldığı için bileşenimizin durumunu koruyabilecektir. Ama bir koşulun içine bir Hook çağrısı koyarsak ne olur?
// We're breaking the first rule by using a Hook in a condition if (accountName !== '') { useEffect(function persistForm() { localStorage.setItem('formData', accountName); }); }
accountName !== ''
koşulu ilk oluşturmada true
, bu yüzden bu Hook'u çalıştırıyoruz. Ancak, bir sonraki oluşturmada kullanıcı formu temizleyerek koşulu false
yapabilir. Artık render sırasında bu Hook'u atladığımıza göre, Hook çağrılarının sırası farklı hale geliyor:
useState('David') // 1. Read the accountName state variable (argument is ignored) // useEffect(persistForm) // This Hook was skipped! useState('Active') // 2 (but was 3). Fail to read the accountDetails state variable useEffect(updateStatus) // 3 (but was 4). Fail to replace the effect
React, ikinci useState
Hook çağrısı için ne döndürüleceğini bilemezdi. React, bu bileşendeki ikinci Hook çağrısının, tıpkı önceki oluşturma sırasında olduğu gibi persistForm
etkisine karşılık gelmesini bekliyordu - ama artık değil. Bu noktadan sonra, atladığımızdan sonraki her Hook
çağrısı da birer birer değişir ve bu da hatalara yol açar.
Bu nedenle, Kancalar, bileşenlerimizin en üst seviyesinde çağrılmalıdır. Bir efekti koşullu olarak çalıştırmak istiyorsak, bu koşulu Kancamızın içine koyabiliriz.
Not : Bu konu hakkında daha fazlasını okumak için React Hook belgelerine bakın.
Yalnızca React Bileşenlerinden Çağrı Kancaları
Normal JavaScript işlevlerinden Hook'ları çağırmayın. Bunun yerine, React işlev bileşenlerinden Hook'ları çağırabilirsiniz. Aşağıdaki JavaScript işlevi ile React bileşeni arasındaki farka bakalım:
JavaScript İşlevi
import { useState } = "react"; function toCelsius(fahrenheit) { const [name, setName] = useState("David"); return (5/9) * (fahrenheit-32); } document.getElementById("demo").innerHTML = toCelsius;
Burada, React paketinden useState
kancasını içe aktarıyoruz ve ardından işlevimizi ilan ediyoruz. Ancak bu bir React bileşeni olmadığı için geçersizdir.
Tepki Fonksiyonu
import React, { useState} from "react"; import ReactDOM from "react-dom"; function Account(props) { const [name, setName] = useState("David"); return <p>Hello, {name}! The price is <b>{props.total}</b> and the total amount is <b>{props.amount}</b></p> } ReactDom.render( <Account total={20} amount={5000} />, document.getElementById('root') );
Her ikisinin de gövdesi benzer görünse de, React'i dosyaya aktardığımızda ikincisi bir bileşen olur. Bu, JSX ve React kancaları gibi şeyleri içeride kullanmamızı mümkün kılan şeydir.
Tercih ettiğiniz kancayı React'i içe aktarmadan içe aktardıysanız (bu, onu normal bir işlev haline getirir), Hook'a yalnızca React bileşeninde erişilebilir olduğundan, içe aktardığınız Hook'u kullanamazsınız.
Özel Kancalardan Çağrı Kancaları
Özel bir Kanca, adı use
ile başlayan ve diğer Kancaları çağırabilen bir JavaScript işlevidir. Örneğin, useUserName
, useState
ve useEffect
kancalarını çağıran özel bir Kancanın altında kullanılır. Bir API'den veri alır, veriler arasında döngü yapar ve aldığı belirli kullanıcı adı API verilerinde mevcutsa setIsPresent()
çağırır.
export default function useUserName(userName) { const [isPresent, setIsPresent] = useState(false); useEffect(() => { const data = MockedApi.fetchData(); data.then((res) => { res.forEach((e) => { if (e.name === userName) { setIsPresent(true); } }); }); }); return isPresent; }
Daha sonra, bu kancanın işlevselliğini, uygulamamızda buna ihtiyaç duyduğumuz diğer yerlerde yeniden kullanmaya devam edebiliriz. Bu tür yerlerde, ihtiyaç duyulmadıkça, artık useState
veya useEffect
çağırmamız gerekmiyor.
Bu kuralı izleyerek, bir bileşendeki tüm durum bilgisi olan mantığın kaynak kodundan açıkça görülebilmesini sağlarsınız.
ESLint Eklentisi
eslint eslint-plugin-react-hooks
adı verilen ESLint eklentisi yukarıdaki kuralları uygular. Bu, bir proje üzerinde çalışırken kuralların uygulanmasında kullanışlıdır. Projeniz üzerinde çalışırken, özellikle başkalarıyla çalışırken bu eklentiyi kullanmanızı öneririm. Denemek isterseniz bu eklentiyi projenize ekleyebilirsiniz:
// Your ESLint configuration { "plugins": [ // ... "react-hooks" ], "rules": { // ... "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies } }
Bu eklenti, Create React App'te varsayılan olarak bulunur. Bu nedenle, React uygulamalarınızı Create-React-App kullanarak önyüklerseniz eklemeniz gerekmez.
Kancalarda Düşünmek
Hooks'un birkaç en iyi uygulamasına dalmadan önce, class
bileşenlerine ve işlevsel bileşenlere (Hook'larla) kısaca bir göz atalım.
React'te bir bileşen tanımlamanın en basit yolu, bir React öğesi döndüren bir JavaScript işlevi yazmaktır:
function Welcome(props) { return <h1>Hello, {props.name}</h1>; }
Welcome
bileşeni, veri içeren ve bir React öğesi döndüren bir nesne olan props
öğelerini kabul eder. Daha sonra bu bileşeni içe aktarabilir ve başka bir bileşende oluşturabiliriz.
class
bileşeni, Kapsülleme adlı bir programlama metodolojisi kullanır; bu, temel olarak, sınıf bileşeniyle ilgili her şeyin onun içinde yaşayacağı anlamına gelir. Yaşam döngüsü yöntemleri ( constructors
, componentDidMount()
, render
vb.) bileşenlere tahmin edilebilir bir yapı verir.
Kapsülleme , OOP'nin ( O nesneye dayalı programlama) temellerinden biridir. Bu veriler üzerinde çalışan yöntemler içinde verilerin gruplandırılması anlamına gelir ve bir sınıf içindeki yapılandırılmış bir veri nesnesinin değerlerini veya durumunu gizlemek için kullanılır - yetkisiz tarafların bunlara doğrudan erişimini engeller.
Hook'larla, bir bileşenin bileşimi, yaşam döngüsü Hook'larının bir kombinasyonu olmaktan, sonunda bazı işlemelerle işlevselliklere dönüşür.
İşlev Bileşeni
Aşağıdaki örnek, özel Kancaların işlevsel bir bileşende nasıl kullanılabileceğini gösterir (gövdenin ne olduğunu göstermeden). Ancak yaptıkları ve yapabilecekleri bunlarla sınırlı değildir. Durum değişkenlerini başlatmak, bağlamları tüketmek, bileşene çeşitli yan etkilere abone olmak veya özel bir kanca kullanıyorsanız yukarıdakilerin tümü olabilir!
function { useHook{...}; useHook{...}; useHook{...}; return (
...); }
Sınıf Bileşeni
Bir class
bileşeni, React.Component
genişletmenizi ve bir React öğesi döndüren bir render
işlevi oluşturmanızı gerektirir. Bu, daha fazla kod gerektirir, ancak size bazı avantajlar da sağlayacaktır.
class { constructor(props) {...} componentDidMount() {...} componentWillUnmount() {...} render() {...} }
React'te işlevsel bileşenleri kullanarak elde edeceğiniz bazı avantajlar vardır:
- Bileşeninizde
setState()
'e erişiminiz yoksa, bileşeninizin durumu hakkında daha fazla düşünmeniz gerektiğinden, kapsayıcı ve sunum bileşenlerini ayırmak daha kolay olacaktır. - İşlevsel bileşenlerin okunması ve test edilmesi çok daha kolaydır çünkü bunlar durum veya yaşam döngüsü kancaları olmayan düz JavaScript işlevleridir.
- Daha az kodla biter.
- React ekibi, gelecekteki React sürümlerinde işlevsel bileşenler için bir performans artışı olabileceğini belirtti.
Bu, React Hooks kullanılırken ilk en iyi uygulamaya yol açar.
Kanca En İyi Uygulamaları
1. Kancalarınızı Basitleştirin
React Hooks'u basit tutmak, kullanım ömrü boyunca bir bileşende neler olup bittiğini etkili bir şekilde kontrol etme ve değiştirme gücü verecektir. Mümkün olduğunca özel Kancalar yazmaktan kaçının ; kendi kancanızı oluşturmak yerine bir useState()
veya useEffect()
öğesini satır içine alabilirsiniz.
İşlevsellikle ilgili bir grup özel Kancadan yararlandığınızı fark ederseniz, bunlar için sarmalayıcı görevi gören özel bir kanca oluşturabilirsiniz. Aşağıdaki kancalı iki farklı fonksiyonel bileşene bir göz atalım.
İşlevsel Bileşen v1
function { useHook(...); useHook(...); useHook(...); return( <div>...</div> ); }
İşlevsel Bileşen v2
function { useCustomHook(...); useHook(...); useHook(...); return( <div>...</div> ); }
v2 daha iyi bir sürümdür çünkü kancayı basit tutar ve diğer tüm useHook
lar buna göre satır içidir. Bu, farklı bileşenler arasında yeniden kullanılabilecek işlevsellik oluşturmamıza olanak tanır ve ayrıca bileşenlerimizi etkin bir şekilde kontrol etmek ve işlemek için bize daha fazla güç verir. Bileşenlerimizin Kancalarla dolu olduğu v1'i benimsemek yerine, hata ayıklamayı kolaylaştıracak ve kodunuzu daha temiz hale getirecek v2'yi kullanmalısınız.
2. Kancalarınızı Düzenleyin ve Yapılandırın
React Hooks'un avantajlarından biri, okunması kolay daha az kod yazabilme yeteneğidir. Bazı durumlarda, useEffect()
ve useState()
hala kafa karıştırıcı olabilir. Bileşeninizi düzenli tuttuğunuzda, okunabilirliğe yardımcı olacak ve bileşenlerinizin akışını tutarlı ve öngörülebilir tutacaktır. Özel Kancalarınız çok karmaşıksa, bunları her zaman alt özel Kancalara ayırabilirsiniz. Kodunuzu okunabilir hale getirmek için bileşeninizin mantığını özel Kancalara çıkarın.
3. React Hooks Snippet'lerini kullanın
React Hooks Snippets, React Hooks'u daha kolay ve daha hızlı hale getirmek için bir Visual Studio Code uzantısıdır. Şu anda beş kanca desteklenmektedir:
-
useState()
-
useEffect()
-
useContext()
-
useCallback()
-
useMemo()
Diğer snippet'ler de eklendi. Bu Kancalarla çalışmayı denedim ve bu, onlarla çalışırken kişisel olarak kullandığım en iyi uygulamalardan biri oldu.
Projenize React Hooks parçacıkları eklemenin iki yolu vardır:
- Emretmek
VS Code Quick open'ı ( Ctrl + P ) başlatın,ext install ALDuncanson.react-hooks-snippets
yapıştırın ve Enter tuşuna basın. - Uzantı Pazarı
'VS Code Extension Marketplace'i ( Ctrl + Shift + X ) başlatın ve 'React Hook Snippet'lerini' arayın. Ardından, 'Alduncanson' simgesini arayın.
İlk fragmanı tavsiye ederim. Snippet'ler hakkında daha fazla bilgiyi buradan okuyun veya en son Hooks snippet'lerini buradan kontrol edin.
4. Kanca Kurallarını Dikkate Alın
React Hooks ile çalışırken daha önce öğrendiğimiz iki Hook kuralını her zaman dikkate almaya çalışın.
- Kancalarınızı yalnızca en üst düzeyde arayın. Döngüler, koşullar veya iç içe işlevler içindeki Hook'ları çağırmayın.
- Hook'ları her zaman React fonksiyon bileşenlerinden veya özel Hook'lardan çağırın, Hook'ları normal JavaScript fonksiyonlarından çağırmayın.
eslint-plugin-react-hooks
adlı ESlint eklentisi bu iki kuralı uygular, dilerseniz bu eklentiyi yukarıda hooks kuralları bölümünde açıkladığımız gibi projenize ekleyebilirsiniz.
Kancalar hala nispeten yeni olduğu için en iyi uygulamalar tam olarak çözülmedi. Bu nedenle evlat edinme, herhangi bir erken teknolojide benimsenirken alınacak önlemle alınmalıdır. Bunu akılda tutarak, Hooks, React'in geleceğinin yoludur.
Çözüm
Umarım bu eğitimi beğenmişsinizdir. React Hooks'un en önemli iki kuralını ve Hooks'ta nasıl etkili bir şekilde düşünüleceğini öğrendik. Hook'ları doğru ve etkili bir şekilde yazmak için işlevsel bileşenlere ve bazı en iyi uygulamalara baktık. Kurallar ne kadar kısa olursa olsun, kuralları yazarken onları yol gösterici pusulanız yapmak önemlidir. Unutmaya meyilliysen, bunu uygulamak için ESLint eklentisini kullanabilirsin.
Umarım bir sonraki React projenizde burada öğrendiğiniz tüm dersleri alırsınız. İyi şanlar!
Kaynaklar
- "Kancalarla Tanışın", React Docs
- "Fonksiyonel ve Sınıf Bileşenleri React'te" David Joch, Medium
- “Zararlı Olarak Kabul Edilen Karışımlar,” Dan Abramov, React Blog
- Bryan Manuele, Medium, "React Hooks: En İyi Uygulamalar ve Zihniyette Bir Değişim"
- “VS Code için React Hooks Snippet'leri,” Anthony Davis, Visual Code Marketplace