Bir önceki makalemde Hookslarla birlikte sisteme dahil edilen React’ın en önemli hazır hooku olan useState’i yazmıştım. Bu makaleyi okumak isteyen arkadaşlar hesabım üzerinden yazıya ulaşabilirler. Hookslarla birlikte sisteme dahil edilen ve hazır olarak gelen ikinci hooks, useEfffect hooku. Bu konuyu tam teşekküllü anlatmaya geçmeden önce isterseniz neden hooksları kullanmalıyız konusunun en önemli amacına tekrar değinelim; Hookslar, react sistemi veya projesi içinde ortak olan durumsal işlevleri ve algoritmaları high order componentların ve render propsların sınırlarına takılmadan kullanılabilir olması için sisteme dahil edilmiştir.
Hooksları kullanmayı gerçekten seviyorum, hatta hookslarla birlikte client tarafından çalışmak artık benim için daha zevkli oldu diyebilirim. Hookslar, react takımı tarafından ilk açıklandığı zaman bir iki ay bekleyip, topluluğun nasıl cevap verdiğini izledim, yazılımcılardan gelen olumlu dönüşlerden sonra bylge.com ‘un bütün altyapısını hookslara taşıdım. Ancak bu süreçte benim ilk olarak useEffect ‘in bileşenler içinde kullanımı biraz zorladı. Bundan dolayı bu konu hakkında kapsamlı bir makale yazmaya karar verdim, sizinde benim gibi aynı acıları çekmenizi istemiyorum. Öylede iyi yürekli bir adamım :)). Hooksların öğrenme sürecinin çoğunu bana göre useEffect’in nasıl kullanılacağı oluşturuyor. Eğer bu konuyu hakkıyla öğrenirseniz inanın bana bundan sonrası çorap söküğü gibi geliyor. İsterseniz hemen konuya girelim;
useEffect adı nereden geliyor ve bileşenler içinde hangi görevi icra ediyor?
React projesi kapsamına çıkarsak, programlamada side effect(yan-istenmeyen etki) dediğimiz bir olgu var. Side effect, fonksiyonun verilen parametreler veya inputlar dışında kendi sınırlarının dışına çıkıp ve farklı görevler yapmasıdır. Eğer yukarıdaki cümle size çok açıklayıcı gelmediyse, kafamıza daha fazla oturması için bunu bir örnekle açıklayalım;
Hemen aşağıdaki eklemiş olduğum fonksiyona birlikte bakalım, gördüğünüz gibi çok masum bir fonksiyon, input olarak adı ve soyadı veriyoruz, fonksiyonda bize birleştirilmiş string halinde Ad ve Soyadı yazdırıp tekrar geri dönüyor. Yukarıdaki cümle kapsamında konuşursak, fonksiyon kendi sınırları dışına çıkmıyor, sadece verdiğimiz inputu alıp, biraz şekil değiştirip output şeklinde veriyor. Sonuç itibariyle biz de rahatlıkla şunu söyleyebiliyoruz. Yukarıdaki fonksiyonun bir side effect yok.
Şimdi aşağıdaki fonksiyona bakalım. Yine aynı fonksiyon ama dikkat ederseniz bu fonksiyon kendi içinde şöyle bir şey yapıyor. DOM üzerinde yer alan <header id=”tahta” /> elementi alarak, bu elementin contentinde güncelleme işlemi yapıyor, daha sonra bize adımızı ve soyadımızı veriyor. Gördüğünüz gibi bu fonksiyon çok masum bir fonksiyon değil, eğer fonksiyonun ismine bakarsanız sadece adımızı ve soyadımızı bir string halinde dönen bir fonksiyon diyoruz, ama fonksiyon bu işi yaparken aynı zamanda html elementi üzerinde de değişikliğe giderek, asıl görevi(ad-soyadı string halinde dönme) dışında, farklı bir misyonda yürütüyor. Bu sebeple, biz bu fonksiyona side effecti olan fonksiyon diyebiliyoruz.
Peki side effect kötü bir şey mi? Kesinlikle kötü bir şey değil, hatta programlama açısından elzem, ancak doğru kullanılmaz ise mantıksal ve tekniksel sürecin bozulmasına neden olur. Fonksiyonlarda side effect kullanırken her zaman tetikte olmanızda fayda var, bazı zamanlarda bileşenlerinin içinde çok derinde kalarak soruna yol açabilir sizde bu sorunu ararken, ben niye yazılımcı oldum diye kendinizi sorgulayabilirsiniz.( kişi kendinden bilir işi).
Bu alt başlığı özetlersek, useEffect ‘in adı react takımı tarafından programlamadaki side effect adından türetilmiştir. Temel görevi, yalın js fonksiyonlardaki side effect işlevini, react bileşenlerinde yerine getirmektir.
useEffect sisteme neden eklendi?
Aslında bu sorunun bir cevabını yukarıda verdim, temel olarak side effect işlevini react bileşenlerinde yerine getirmek. Aslında bu sorunun, react öğrenmeye hookslarla değilde,benim gibi life cycle(sınıf bazlı bileşenler) ile başlayan arkadaşlar için ikinci bir cevabı da var. Eğer siz react öğrenmeye hookslarla başladıysanız yine bu başlığı okumanızı şiddetle tavsiye ediyorum.
React 16.8* ‘den önce ile bileşenler üzerimizdeki side effect işlemlerini yaparken(api call, dom update, state check out, vb..) life cycle metodların kullanmak zorunda kalıyorduk. Ancak bunlar bugünkü useEffect kullanımından çok ama çok zordu. Eğer benim gibi bir site üzerinde tek başına çalışıyorsanız saç baş dağılmış bir şekilde ayna karşısına geçip kendi kendinizle şöyle konuşmaya başlıyordunuz. Benim zaten sitenin bakımı için bir sürü işim var; js frameworkünü mü yöneteyim, layout mu tasarlayayım, server tarafından verimi işleyeyim, orm ‘in bakımını yapayım, database mi kontrol edeyim, 3.parti bağlantılarını mı yapayım, aws servislerim ne durumda diye mi bakayım, github pushlarıma mı dikkat edeyim … vs bunlarla uğraşırken birde neredeyse bunlar kadar zaman alıcı bir life cycle olayı vardı. Bu kadar zormuydu evet bana göre müthiş zordu, bir noktadan sonra kademeyi kaybediyordunuz. Aşağıda eklemiş olduğum resme bakarsanız, gördüğünüz gibi life cycle süreci master degree uzmanlık isteyen bir süreçti.
Bu sebepten dolayı, özellikle Amerikalı yazılımcılar bir noktadan sonra React’a bayrak aştı, artık bileşenlerin yönetilemez olduğunu ve zorlandıklarını her yerde yazmaya başladılar. React takımının en sevdiğim huyu topluluk üzerinden gelen bu eleştirilere kesinlikle cevap veren bir yönetiminin olması. React takımı dile getirilen bu sorunlar çerçevesinde hemen aksiyon aldı ve yukarıda açıklamış olduğum sebeplerden dolayı useEffect sisteme kazandırarak bileşenler üzerindeki life cycle katliamına son verdi.
useEffect nasıl kullanılır?
1. Birinci Kullanımı
useEffect kullanımını biraz garip, react takımıda şimdilik idare edin ileride biz daha iyi bir kullanım sunacağız dediler. Bence hiç gerek yok, kullanımı gayet basit ve anlaşılabilir. useEffect, iki tane parametre alıyor birincisi useEffect içerisinde çalıştıracağınız callback fonksiyonu, ikincisi de bu callback fonksiyonun çalışmasını kontrol edebileceğiniz array dizisi. Boş kullanımı aşağıdaki gibi ;
Hemen isterseniz yukarıda vermiş olduğum bileşende, useEffect’i basit bir şekilde kullanalım. İlk olarak bileşenim içerisine <p> elementi ekliyorum, daha sonra useEffect içerisinde bu elementin textini değiştiriyorum ve sonucu en son render ediyorum. Kod kullanımı ve çıktısı aşağıdaki gibi;
Yukarıdaki gördüğünüz gibi useEffect tam istediğimiz gibi çalıştı ve <p> elementinin içerisinde güncelleme işlemi yapabildim. Buradan şöyle bir sonucu varıyoruz, bileşen mount edildikten sonra useEffect react tarafından çalıştırılıyor ve biz side effect işlemleriniz yapabiliyoruz.
2. İkinci Kullanımı
Yukarıdaki örneği biraz değiştirmek istiyorum, aşağıdaki eklediğim kod görüntüsüne bakarsanız bileşene iki tane useEffect ekledim, ayrıca HelloUseEffect bileşeninin içine son eklediğim useEffect ile kontrol edebileceğim bir <p> elementi de yerleştirdim. Ayrıca son olarak button ile durumunu kontrol edebilmek için bir buton koydum. Şimdi bu butona bastığımız zaman neler oluyor ona bakalım?
İsterseniz yukarıdaki ekran görüntülerine açıklamaya başlayalım. Eklediğimiz useEffect fonksiyonların içinde, reacta şöyle bir şey dedik, her state değişiminde aşağıdaki eklemiş olduğum <p> elementlerinin background renklerini yeşilden kırmızı güncelle. Bu işlemi yapabilmek için ise bir buton ekleyerek her tıkladığımızda state durumunda değişikliğe gittik. Ancak bu örneği sizde yapar ve butona basarsanız, bu elementlerden sadece bir tanesinin background renginde değiştiğini göreceksiniz. Bunun sebebi, koda isterseniz dikkatli bir şekilde tekrar bakalım, ikinci olarak eklemiş olduğum useEffect içinde kullandığımız callback fonksiyonunu kontrol eden diziyi boş olarak kullanmamız. Böyle bir kullanım reactta şöyle bir sonuca neden oluyor, eğer callback kontrol eden dizi boş olarak verilirse, react bileşeni mount ettikten sonra sadece bir kere veya diğer bir deyişle sadece ilk renderdan sonra useEffect fonksiyonunu çalıştırıyor. Eğer api call işlemi yapacaksanız, çağırma işlemini bu şekilde rahatlıkla yapabilirsiniz. Eğer her render arasında useEffect çalıştırmak istiyorsanız koşul olarak bir şey vermenize gerek yok.
3. Üçüncü Kullanımı
2.kullanımdaki örnekte, array dizisini boş kullanarak useEffect’in sadece mounttan sonra bir kere çalışmasını sağladık, mesela ben bu özelliği bylge.com ‘un ana sayfasında kullanıyorum. Ana sayfayı render ettikten sonra, boş dizeye sahip bir useEffect kullanarak apiden verilerimi alıyorum. Bu yüzden her render arasında tekrar apiyi çağırmak zorunda kalmıyorum. useEffect’in üçüncü ve son kullanımı ise şöyle; bazı durumlarda useEffect’i bileşen içerisinde birden fazla çağırmanız gerekebilir ancak her renderda da çalışmasını istemezsiniz. Bu durumda useEffect’i nasıl kullanmak gerekiyor?. Yine aşağıdaki ekran görüntülerine bakarsanız, bileşene ek olarak changer2 adında bir tane daha durum ekledim, bu şekilde bileşendeki toplam durum sayısı changer1 ve changer2 olmak üzere iki tane oldu. Bu durumlardaki değişikliklere bağlı olarak useEffect fonksiyonlarının koşul dizilerine bu durumları ekleyerek çağırdım. Sizde örneği yaparsanız birinci butona basıldığı zaman ikinci <p> elementin backgroundda değişlik olmadığını farkedeceksiniz veya ikinciye bastığınız zaman birincide herhangi bir değişiklik olmayacak. Bu şekilde durumlara bağlı olarak useEffect’te side effect işlemlerini koşulla şekilde yapabilirsiniz. Peki üçüncü kullanımda illaki bu koşul dizisi bir durum olmak zorunda mı? Hayır, mutlaka state olmak zorunda değil, bu parametre bir değişken veya bileşen propu olabilir. Bileşen içinde değişikliğe uğrayacak herhangi bir değişken burada kullanılabilir.
useEffect’in temel kullanımı bu kadar, useEffect’in diğer hookslarla birlikte ileri kullanımları var, ancak şimdilik bunlar bilmeniz gereken şeyler değil, projeniz çok fazla büyür ve performans sorunları yaşarsanız, ileri kullanımlarına geçebilirsiniz. Eğer beğendiyseniz üye olmayı ve yorum yapmayı unutmayın. Eğer sorularınız veya anlatılması istediğiniz konular var ise lütfen yorumlarda belirtin. Herşey gönlünüzce olsun.
İyi çalışmalar