Kıssadan React [Yaşayan Yazı]
Yaşayan Yazı, bir yerimden uydurduğum bir terimdir ve ileriki dönemde içeriği zenginleşecek ama şu anki haliyle de faydalı olabilecek yazıları belirtir.
Yeni React dökümantasyonunun çıkmasıyla birlikte baştan takip etmek istedim. Dolayısıyla sıfırdan öğrenen birisine yardımcı olacak kilit noktaları az ve öz paylaşıyor olacağım.
Genel
- React'ın "Strict Mode"u development esnasında her komponent fonksiyonunu iki kez çağırır ve Pure olmayan komponentleri yakalamanızı sağlar.
- Animasyon ve ekranın yenilenmesi gibi işlemler side effect olarak adlandırılırlar. Renderlama anında değil yanında meydana gelen şeylerdir.
- Uygulama başladığında yalnızca bir kez çalıştırılacak kod komponent dışına koyulabilir.
Rendering
- React komponentler esasen render edilmek üzere HTML döndüren fonksiyonlardır. Aslında HTML gibi dursa da JSX dediğimiz ve HTML çok benzeyen bir uzantı kullanır. Kendisi de JS olduğundan kodların elementlerle kullanılmasını kolaylaştırır. Nihayetinde kendisi de HTML'e çevrilir.
- Tek bir element/komponent döndürmesi gerekir. Eğer iç içe olmaması gereken bir şeyler varsa etrafına
<div>
ya da<>
sarabiliriz.
- Child komponenti yoksa her zaman kapanan etiket (closing tag) ile yazmalıyız.
- Birden fazla element return edilemez. Bunları
<div>...</div>
ya da<>...</>
etrafına sarmalıyız. İkincisinin adı Fragment olarak geçer ve HTML'e ekstra bir element eklemeden bu işi görür. Sebebi ise bir fonksiyonun array olmadığı takdirde birden fazla sonuç döndürememesidir.
- JavaScript değişkenleri ve ifadelerini (expression) JSX'de süslü parantez ile kullanabiliriz.
- Koşullu render için 3 farklı yaklaşım uygulayabiliriz.
false
,null
veundefined
değerleri JSX'de gözardı edilir.
- Koşullu render yapmak istersek
condition ? result1 : result2
,condition && result
şeklinde kısaltma ya daif
koşulunu kullanabiliriz.
- Listeleri render etmek istersek array metodlarıyla ürettiğimiz JSX element
element listesi kullanabiliriz. Burda dikkat edilmesi gereken listedeki
değişikliklere adapte olabilmesi için elementlere
key
özelliği iletilmelidir. Aksi halde indeks değerleri kullanır ve elemanların sıraları değişirse ya da içlerinden birisi silinirse doğru şeyleri render edemez.
key
olarak uuid üreten bir kütüphane yada apiden dönen id değerini kullanabilirsiniz. Aksi halde şu hatayı alırsınız: 'Warning: Each child in a list should have a unique “key” prop.'
key
özelliğine her seferinde rastgele değer üreten bir metod verilirse (örneğin Math.random) DOM'a her seferinde yeniden render edilir.
- Normal davranışta React değişen state ile birlikte ilgili tüm işlemler bittikten sonra DOM'u günceller. O kodun arkasından state değişikliğiyle gelecek yeni DOM'a erişmemiz gerekirse
flushSync
metodunu kullanabiliriz.
Event Handler
- Olaylara tepki gösterecel fonksiyonlarımızın ismini elementlere iletebiliriz. Çağrı parantezlerini eklerseniz render edilirken fonksiyon tek sefer çağrılır. Varsayılan olarak fonksiyona
Event
nesnesi geçilir ancak ekstra veri göndermek istersek arrow function kullanabiliriz.
- Fonksiyon çağrılırsa rendering esnasında çalıştırılır.
- Elementlerin beklediği event props isimlerinde
on
, handler isimlerindehandle
ile başlamak yaygındır. Örn:onMouseEnter={handleMouseEnter}
- Event propagation komponentlerde de geçerlidir. Örnekte önce button sonra div
onClick
metodu çağrılır.onScroll
harici tüm olaylar yukarıya yayılır. Engellemek içine.stopPropagation()
kullanılır.
- Formun
onSubmit
olayı gibi bazı olaylar varsayılan tarayıcı davranışına sahiptir ve sizin kodunuzdan sonra çalıştırır. Bunu engellemek içine.preventDefault
kullanabiliriz. - Event handler'ları yukarıdan aşağıya doğru (capturing) çalıştırmak istersek
onClick
yerineonClickCapture
kullanımını yapabiliriz.
=== Output:Call 2 Call 3 Call 1
Props
- Bileşenden bileşene veri aktarmak için
props
kullanırız. Klasik fonksiyona parametre geçme mantığı.
- Children elementleri props'un
children
özelliğinden okuyabiliriz.
State
- Zamanla değişebilen ve ekranın güncellenmesine yol açacak değerler için state değişkenlerini kullanırız. Bi nevi komponent bazlı bellektir. Render'lar arasında değeri korunur.
- State komponentin DOM'daki yeriyle ilişkilendirilir. State'in rerender'lar esnasında korunmasını istiyorsanız, DOM ağacının yenisiyle 'eşleşmesi' gerekir. Eğer aynı konumda render olan komponentlerde state'i sıfırlamak istersek farklı
key
parametresi verebiliriz. - React'da state tanımlamak için
useState
hook'u kullanılır.
React'da
use
ile başlayan fonksiyonlarahook
diyoruz ve esasen React'ın özelliklerini kullanabilmemize yarıyorlar. Komponentlerin root'unda kullanılabilirler. Koşul ya da döngü içine kullanmamalıyız. Gerekiyorsa yeni bir bileşen oluşturabiliriz.
- State setter çağırıldıktan sonra rerender tetiklenir ve yeni değer kullanılır.
- React Hook'ların değerlerini çağrılma sırasına göre anlar. Arka arkaya tanımladığımız state değerleri dizide tutulur ve okunacağı zamanda indeksi birer arttırarak okur. Bu sebeptendir ki sadece komponentin root'unda tanımlanmalıdır.
- Obje tutuyorsak spread kullanmayı unutmamalıyız.
- State güncelleme metodu çalıştığı anda değeri yenilemez. Örnekte üç kez çağırılan setNumber metoduyla birlikte son değerin 3 olmasını bekleyebiliriz ancak öyle olmaz. Her bir setter çalıştığında state değeri mevcuttaki değer yani 0'dır. Metod çalışmayı bitirdikten sonra rerender olur ve state değeri güncellenir. Komponent context'deki değeri elde etmek istersek parametre olarak güncel değeri alan updater fonksiyon verebiliriz.
- Karmaşık state'leri yönetmek çok karmaşık olabilir. React'ın
useReducer
hook'u ile reducer oluşturup kullanılabiliriz. Esasen alınan aksiyonlar sonunda yapılacak state değişikliklerini tanımlamamızı sağlar.
Ref
- Referans tanımlamak için
useRef
hook'u kullanabiliriz. Değeri render'lar sırasında korur ancak rerender'a sebep olmaz. Event handler içerisinde kullanılabilir. Belirli bir event yoksa Effect ihtiyacı olabilir.
- Elementlere verilen ref rendering esnasında çalıştırılan komponent gövdesinde olmamalıdır.
- Ref'leri map içerisinde kullanamayacağımızdan ötürü ref callback kullanmalıyız.
- DOM elementlerini manipüle etmek istersek
ref
parametresini kullanabiliriz.
- Komponente ilettiğimiz ref otomatik olarak DOM'a eklenmez. Bunun için
forwardRef
API'sinin kullanılması gerekir.
Context
- Props'ları komponentler arasında 100 kat aşağıya indirmek yerine bir context tanımlayıp
useContext
hook'u yardımıyla okuyabiliriz.
Effect
- Komponentlerin harici sistemlerle senkronize edilmesi için rendering sonrasında kod çalıştırmak için kullanılır. React harici bir komponentin yönetilmesi, sunucu bağlantısının kurulması analitik log'u gönderilmesi vs. Render'ın sebep olduğu yan etkileri gerçekleştirmek için kullanılır. Render'dan sonra çalışır.
useEffect
metodu kullanılır.
- Sunucuda yani server-side rendering esnasında çalışmaz.