Reselect kullanarak React uygulamalarınızdaki Redux performansını artırın!

Berk Safran
Huawei Developers - Türkiye
4 min readMar 16, 2020

Frontend dünyasının en popüler kütüphanelerinden biri olan React.js kullanarak geliştirdiğimiz uygulamalarımızın Redux performansını nasıl artırabiliriz?

Cevap bu dokümanda!

Başlamadan önce dikkat etmemiz gerekenler:

  • Bu dokümanda daha önce React.js ile Redux kullandığınız varsayılmıştır.
  • Dokümandaki redux kullanımı React Hooks ile gerçekleştirilmiştir. Class bazlı kullanımı istek gelirse daha sonra ekleyebilirim.
  • <App> componentimizi kapsayan Redux fonksiyonları bu dokümanda yer almamıştır, ama bunların uygulandığı varsayılmıştır.

Lafı daha fazla uzatmadan, önce problemimiz nedir bir anlayalım:

Öncelikle pets.js dosyasında yer alan reducerımıza bakalım:

ve main.js dosyamız:

Uygulamamızın ekran görüntüsü ve console çıktısı:

Console’da da görüldüğü üzere;

  • İlk açılışta hem componentler içerisine yerleştirdiğimiz console.log’lar hem de selectorlar içerisindeki console.log’lar çalıştı ve yukarıdaki çıktıyı verdi.
  • Peki, Change Dogs veya Change Cats butonlarına bastığımızda console’da ne gibi bir çıktı geliyor? Bakalım..

Gördüğünüz gibi tanımladığımız 2 selectorda çalıştı ve içinde yer alan console.log’lar tekrar ekrana basıldı. (“Dogs” ve “Cats”)

Ufak bir not: main.js dosyasına göz atarsanız React Memo kullanıldığını farkedebilirsiniz. Bu kullanım, bir butona bastığımızda alakası olmayan diğer component’in tekrar re-render edilmesini engelliyor. Böylece performansta bir verim artışı meydana geliyor. Change Dogs butonuna bastığımız için console’da da gördüğümüz üzere “Dogs rendering..” ekrana basılıyor, “Cats rendering” ekrana basılmıyor. Daha detaylı için React Memo kullanımını araştırabilirsiniz.

Tamam da ben problemi hala anlayamadım?

Problem, biz “Change Dogs” butonuna tıklayarak, sadece dogsData olarak tanımladığımız selectorın çalışmasını dilememize rağmen state içerisinde bir değişim olduğundan dolayı catsData selectorın da çalışması. Yani, hangi butona tıklasak 2 selectordan birinin gereksiz yere çalışması.

Amacımız, aynı React Memo mantığında olduğu gibi değişmeyen bir durum olduğunda selectorın gereksiz yere çalışmasını engellemek.

Çözüm: reselect !

reselect kütüphanesi özellikle işlenmiş, türetilmiş (derived) dataların selectorler içerisinde kullanımını daha efektif bir şekilde sağlıyor. Eğer selectorın içerisinde yer alan data değişmemişse hafızada tuttuğu datayı döndürüyor ve selectorın gereksiz yere çalışmasını engelliyor.

Şimdi çözüm için öncelikle reselect kütüphanesini projemize ekleyelim ve selector.js adında bir dosya yaratalım. Dosyanın içerisine ise reselect’te bulunan createSelector metodunu kullanarak yeni selectorlerimizi tanımlayalım:

createSelector metodu ilk argüman olarak bir callback fonksiyon alıyor ve burada selectorın bağlı olduğu datayı belirtmemizi istiyor. reducer.js dosyasına baktığımızda dogsDataMemo selectorımıza dogs objesini bağlamamız gerektiğini görebiliriz. İkinci argüman olarak bir sonuç fonksiyonu belirtmemizi gerekiyor. Bu fonksiyon içerisinde kendinize göre filter, map vb. metodları kullanarak türetilmiş, yeniden düzenlenmiş datalar return edebilirsiniz. Biz bu örnekte, çalışmasını kontrol etmek amacıyla console.log ekledik ve objecti olduğu gibi return ettik.

Daha sonra, main.js dosyamız içerisine dogsDataMemo ve catsDataMemo fonksiyonlarını import ettik ve useSelector() argümanı olarak ekledik. main.js dosyamızın yeni hali:

Son olarak, problemimizin çözülüp çözülmediğini anlamak için mini uygulamamızı çalıştıralım ve console çıktılarına bakalım:

Çıktıda da görüldüğü üzere Change Dogs butonuna basıldığında sadece ilgili selector çalıştı ve biz böylece uygulamamızın Redux performansını artırmış olduk.

Sonuç

Örnekteki gibi mini uygulamalarda bu tür problemler çok önemsiz olarak gözükebilir ama büyük bir projede yer aldığınızda bu tip ufak iyileştirmeler, performans artışları uygulamanızın daha verimli ve hızlı çalışmasını sağlayacaktır.

Ufak bir not daha: Kod paylaşımını bilerek Gist üzerinden yapmadım. Kopyala/Yapıştır yapmak yerine tek tek kodları yazmanın öğrenmede daha kalıcı olduğunu bir çok defa tecrübe ettim. Siz değerli geliştiricilere de öneririm.

Doküman ile ilgili geri bildirimleriniz benim için çok önemli. Düşüncelerinizi, eklemek istediklerinizi yorum olarak yazabilir ya da berksafranbolulu@gmail.com adresine mail atabilirsiniz.

Sağlıcakla kalın.

— Berk Safran

--

--