Photo by Dan-Cristian Pădureț on Unsplash

React Hooks — useEffect Nedir ?

Hook konusunda seriye devam ediyoruz. Bu yazıda React içerisinde gelen useEffect Hook üzerinde duracağız.

Bu konuya başlamadan önce serinin ilk iki yazısı olan React Hooks Nedir ? ve React Hooks Neden Çıktı ? yazılarını okumanızı öneririm..

React Hook bileşenler için ortak bir takım davranışların kanca atılarak sağlanması olduğunu anlatmıştım. Aynı aşağıdaki resimde olduğu gibi.

Bir önceki yazımızda useState bahsetmiştik. Bu yazımızda da bileşenlerin dışarıya etkisi, bileşen dışı etkileşimi yani SideEffect useEffect Hook’ları ile yapmanızı sağlar.

SideEffect kavramından Fonksiyonel Programlamada bahsetmiştik. Detay için aşağıdaki 2 yazıyı okuyabilirsiniz.

React Bileşenlerinde Network ulaşıyorsanız, DOM’a ulaşıyorsanız yani WebAPI üzerinden veya sunulan kütüphaneler ile bu bileşen dışında bir etkinizi göstermek istiyorsanız bunu useEffect içerisinde yapmanız gerekiyor.

  • Yeni bir effect ekleme.
  • Skip ederek bir sonraki durumda effect etkili olmasını sağlama
  • Effect’i temizleme

1. useEffect Nasıl Çalışıyor ?

Yapısına gelince siz React kütüphanesi içerisinden useEffect çağırırken bir callback fonkiyon geçiriyorsunuz bu callback fonksiyon bileşen her render edildikten sonra çağrılıyor(invoke) ediliyor.

console.count ve document.title bu bileşen dışındaki tarayıcı ile ilgili Console ve Document.title Etkilediği için bunu useEffect içerisinde çağırıyoruz.
https://codesandbox.io/s/useeffect-counter-fcdgp

Bu kodun çalışmasını debug ederek biraz çalışma mantığını anlayabiliriz. Örneğin ekranı refresh ettik. Counter fonksiyonu 2 defa çağrıldı useState ve useEffect ile ilgili state bağlantısı kurulup, side effect callback fonksiyonu set edildi.. 2nci yazdığında aynı fonksiyon önceki callback fonksiyonun üzerine tekrardan yazıldı… ve dönen JSX alıp ekrana bastı.. VDOM → DOM güncelledikten sonra artık bileşen SideEffect dışarı yansıtabilir dendi ve

Sonrasında sayıyı bir arttırdığımda bileşen tekrar render edilecek. Ama bileşen render fonksiyonun ilk çağrımı değil , 2nci çağrımı sonrasında yapılıyor…

Bunun nedeni şundan kaynaklanıyor diye düşünüyorum. useEffect yaptığımız callback state göre değiştirmek istersek. Arada bir render etmeyen fonksiyon çağrımı bize bu avantajı sağlar diye düşünüyorum.

Örneğin fonksiyonumuz aşağıdaki şekilde güncelleyelim. count %2 göre çıkan değerlerde farklı farklı effectler uygulamak isteyelim.

Counter kodunun %2 göre güncelledik

Aşağıda görüleceği gibi Fonksiyonun ekstradan çağrım, bazen useEffect bazende useEffect XXX çağırabilmemize olanak sağlıyor..

Counter kodunun %2 göre Cıktısı…

2. useEffect İçerisindeki değişiklik State Güncellerse Ne Olur ?

Aşağıdaki kodumuz inceliyelim. GitHub Profile bilgisi için GitHub API’den veri çekeceğiz. Burada yanlız ilginç bir durum var..

useEffect içerisinden setProfile çağırıyoruz yani State Güncellemesi yapıyoruz.

Diyebilirsiniz ki bunun ne etkisi var ?

//https://codesandbox.io/s/useeffect-infinite-loop-tczzm?file=/src/index.js:62-718

Bu durumda setState DOM güncelleyecek ve useEffect çağıracak, useEffect tekrar GitHub API’sinden ilgili profile çağıracak ve onun sonucunda tekrar state güncellenecek vs.. şeklinde sürekli bir Cyclic Infinitive Loop girmiş olacak fonksiyonumuz.

Bunu engellemek için useEffect sonuna bir scope veriyoruz. İçi boş bir array verdiğimizde [] useEffect ne olursa olsun 1 kere çağrılır oda Bileşen Initial Render dediğimiz DOM ilk çizildikten sonra..

Bileşene Input Ekleyerek buradan gelen değerle değişimine göre useEffect çağrılsın dersek burada da bir scope vermemiz gerekiyor [input] useEffect scope/bağımlılık olarak verdiğimiz için sadece input değiştiğinde çağrım gerçekleşecektir.

useEffect çağrımını belli değişkenlerin değişimine bağladık…

Önemli Not: Büyük projelerde özellikle Sunucu(server) search veya liste veri çekiyorsanız bu aşamada kullanıcının her klavye basışında input değişeceği için bu Rendering çabası Main Thread kilitleyebilir veya yavaşlatıp ekranınızın flick ederek gözükmesine neden olabilir. Bu durumları nasıl engelleyebileceğinizi … Input Alanları UI Neden Bloklar ? yazımdan okuyabilirsiniz. Burada ufak bir çözüm öneriside içeriyor.

3. useEffect İçerisindeki SideEffect Bağımlılıklarını Temizlemek.

useEffect içerisinde bir takım subscription yaptınız. Ve bileşen render artık ekrandan çıkarılsa bile bu bağımlılıklar devam edecek…

Counter örneğimizi biraz daha değiştirerek setInterval kodu ile 1 saniyede bir ekrana HELLO yazdıralım… Ve bileşeni ekrandan kaldırdığımız da setInterval çalışmasını istemiyoruz …

Bu durumda Başka bir bileşen Render edilmesine geçince bu bileşen ekrandan çıkarıldığında HELLO devam ediyor mu ?

Evet. İsteMEdiğimiz bir durum oluştu. Bileşen Render etmiyoruz ama etkisisi devam ettiriyor. Bu diğer bileşen ve Application için istenmeyen bir durum.

bileşen render edilmese bile HELLO yazmaya devam ediyor

Counter4 Bileşeni useEffect içerisinde geriye bir fonksiyon return edildiğinde bu fonksiyon useEffect callback çağrılmadan önce bu return fonksiyon çağrılır ve burada sideEffect oluşan subscription kaldırabilirsiniz.

Yukarıdaki kod çalışırken, bu bileşen rendering veya ilgili subscription eklenmiş entity değişmesi sonucu unsubscribe işlemi yapabilmenize olanacak sağlar.

Source Kod

GitHub kodu

Referanslar

https://ui.dev/

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke tıklayabilirsiniz.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store