Photo by Karlis Dambrans on Unsplash

FRONTEND KAPSAM

React Query

React Query, Sunucu ile istemci arasındaki State Yönetimini kolaylaştıran bir kütüphane. Bu yazımda daha çok bu kütüphanenin sağladığı avantajlar ve geliştirilme motivasyonu üzerinde duracağım.

Frontend Development With JS
6 min readJan 19, 2022

--

React Query kütüphanesi sunucu ile istemci(client) arasında state yönetimi sırasında karşınıza çıkacak zorlukları geliştiriciden akıllıca soyutlayan data fetching kütüphanesidir. (Zorluklar * fetching, caching, synchronizing, and updating server state)

Tanner Linsley bu kütüphaneyi geliştirirken Server State ve Client State kavramlarını birbirinden ayırıyor.

Client State !=  ServerState 

Bu kütüphanenin yazım amacını anlamak için bu 2 state arasındaki kavramları iyi anlamak gerekiyor.

Client State

  • Kalıcı kaydedilmesi gerekmiyor.
  • useState veya useReducer , Local/Session Storage tutma
  • Sync olarak güncellenebilen veri

Server State

  • Uzakta kaydediliyor
  • Async
  • Paylaşılmış Sahiplik
  • Verinin geçerliliğini yitirmiş olabilir.

Server State != Client State bu farklılıkları doğal olarak bunu gösterdiğiniz UI bileşenlerininde farklı farklı state ele alınıp bunlar için ekstra işler yapmanızı gerektirir.

Örneğin aşağıdaki Sign-in örneğinde olduğu gibi Login düğmesine bastığınızda, verinin sunucuya gönderilip, geri gelmesi sırasında birden farklı durumda UI Bileşenlerini Render etmeniz gerekir. (Fetching/Loading, Successful, Error vb…)

https://onurdayibasi.dev/sign-in

Server State uygulamanız içerisinden kontrol edip, yönetmenizin getirdiği bir takım zorluklar bulunur;

  • Caching: Önemli bir konu, Cachelenmiş veri sayesinde, tekrar tekrar network request yapmayı engeller ve ekranda daha az loading… durumu gösterdiğimiz için ekran geçişleri daha kaliteli ve akışkandır. Problem ise cache verinin geçersiz olduğunu anlayıp kullanıcıya yanlış veri göstermemek için bir takım ekstra işler yapılması gerekmektedir.
  • Deduping Request: Web uygulamaları kullanıcı aksiyonları sonrasında oluşan eventler doğrultusunda veya dış kaynaklardan gelen eventlerin başka eventleri üretmesi doğrultusunda çalışır. Örneğin siz kullanıcının her düğmeye basışında veya keyboard tuşlarına başısında network request gönderiyor iseniz ve bunlar arasında bir debouncing mekanizması yok (Debounce ile ilgili yazı)ise, özetle request cevabı sunucudan gelmeden arka arkaya request atan sisteminiz var ise bu UI da doğru veriyi gösterme aşamasında bir takım problemlere neden olacaktır. Hangi dönen response valid bunu anlayıp digerlerini elemeniz gerekir.
  • Background Updates:Arka planda sürekli olarak kontrol etmeniz gereken sisteme herhangi bir bildirim geldimi, veya bir takım veri gruplarınızda güncelleme olup olmadığını sunucuya gidip sorduğunuz mekanizmalardır. Bu tür yapılarda Long Polling dediğimiz belli aralıklarla fetch işleminin gerçekleştirebilir, Veya Server-Sent Events (SSE) sunucu push teknolojisi ile istemcilere tek yönlü veriyi HTTP Connection ile geçirir. Veya WebSocket üzerinden kurulmuş çift yönlü bir iletişimde Server istediği bilgileri istemciye geçirir.
  • Outdates Requests: Süresi geçmiş istekler. Bunun farklı farklı nedenleri olabilir. Örneğin bu istekten daha sonra benzer bir istek atılmış veya kaynak üzerinde işlem yapılmak istenen kaynak öncesinde başka birileri tarafından silinmiş olabilir.
  • Mutations: Sunucudaki verinin tümü veya bir parçası üzerinde bir takım değişiklikler yapıp bunun sonuclarını UI yansıtılması. Tabi burada objenin içerisinde mi bir değişiklik oldu, bir array elemanlı yapıda mı ?. Yeni bir eleman mı eklendi yoksa eleman mı silindi ? Tüm bunların yansımasının iyi bir şekilde ele alınması gerekir. Bazı kısımlarda kullanıcıya daha problemsiz bir etkileşim sağlamak için Optimistic Updates deneyebilirsiniz.
  • Pagination /Incremental Loading : Pagination işlemleri sırasında tutulan sayfa bilgileri nasıl yönetilecek, bu sayfaların yüklenmesi async olarak nasıl gerçekleşecek, Infinite Page Scrolling bunun UI ile etkileşimi nasıl olacak ?
  • Garbage Collection ve Memory Implications: Kullanılmayan verilerin bellekten atılması ve tüm yukarıdaki işlemlerin belleğe olan etkisi

REACT QUERY

React Query analiz ederken kullanacağımız repo React Query Blog Refactor Example. Bu repoyu aşağıdaki şekilde görüntülemek için bu linke tıklayın

https://onurdayibasi.dev/github-explorer/v2/tannerlinsley/react-query-cached-in-60-minutes

A. Loading, Error, Success Flagları ve Diğer Esktra Bilgiler

Redux ile Backend bir sorgu gerçekleştirdiğimizde action içerisinde aşağıdaki gibi bir durumu yönetmemiz gerektiğini

Foo Fetching

Bu durumu her Backend Call yaptığımız yerde tekrar etmemek için redux-promise-middleware kullanılabileceğimizi (Flux Mimari Örüntüsü) anlatmıştık. Burda verdiğiniz ana state kendisi sonlarına _PENDING, _FULFILLED, _REJECTED ekleyerek sizin tekrar tekrar aynı kodları yazmanızı engelleyecektir.

redux-promise-middleware

Peki Reducer kısmında neler yapmamız gerekiyor du ? Bu ekran ile ilgili Loading, Error vb. flag oluşturup bunları bir State içerisinde yönetmemiz gerekiyordu.

Peki React Query bu yapıyı nasıl handle ediyor ? Bu konuyu oldukça basit bir şekilde sizden soyutluyor. Yapılan işlemler sonrasında veriyi/datayı başka bir obje ile kaplayıp içerisine ekstra değişkenler ekliyor.

React Query useQuery sonrasında dönen verideki ekstra parametreler
  • error: Hata mesajını içerir
  • failureCount: Network Çağırım kaç defa hata aldığını gösterir
  • isError: Network Çağırım sırasında hata olup olmadığını
  • … daha detaylı bilgi için useQuery dokümentasyonunu okuyabilirsiniz.

Yukarıdaki obje sayesinde bileşen state yönetmeniz oldukça kolay bir hale gelir.

B. Caching

Bir diğer problem ise eğer veriyi Redux cache içerisinde tutmak istiyorsanız, bir requestId veya uniqueId ile bu objeyi tutmanız ve bu Cache olan obje üzerinde herhangi bir çağırım yapılacağı zaman bu bu Cache verisi stale olmamış ise çağırmamanız gerekir. Veya belli yerde hata aldı, bir süre çağırmayıp belli bir süre sonra bu cache yenilemesine izin vereecek logicleri siz kendiniz yazabilirsiniz.

React Query kısmında Caching daha komplike ve daha iyi soyutlanarak ele alınmış. Aşağıdaki şekilde bir işleyici bulunuyor. (Link)

C. Callback Handling

Bu kısımda yaptığınız Call işleminin arkasından esktra işlemler yapma ihtiyacı duyabilirsiniz . Örneğin onSuccess başka bir sayfaya yönlendirme, cache invalidate etme vb.. Bunun için yaptıgınız Redux dispactch kodunun çevresine kendi CallbackHandler yazarak bu yapıyı sağlayabilirsiniz.

dispatchCallback Handler

React Query’de bu yapı otomatik olarak size sunuluyor. useMutation ek bir obje içerisinde bu onSuccess ve onError istediğiniz callback fonksiyonları tanımlayanbiliyorsunuz

Callback Options

D. Optimistic Update

İstemciden sunucuya giden istek sırasında karşıdan bu işlemin sonucu gelmeden , istemci tarafında bu işin başarılıymış gibi davranıp aksi durumda bu işlemi rollback yapmanız gerekiyor.. (Sidekick uygulaması için Link)

Sidekick TracePoint Eklenmesi

Sidekick şöyle bir işleyiş bulunuyor. Sizin sunucularda (docker, fargate, EC2 vb..) çalışan microservisleriniz bulunsun. Ekrandan bir Tracepoint koyduğunuzda Broker bu TracePoint alıp ilgili microservislere bağlayıp size TracePoint koyduğunuz yer ile ilgili bilgi dönüyor.

  • Yukarıdaki videoda gördüğünüz gibi ilk TracePoint koyduğumuzda bu ekranda Gri renkli bir şekilde koyuluyor.. Bu işlem sırasında UI Brokerdan cevap gelmesini beklemeden bu işlemi yapıyor.
  • Diyelim ki Websocket üzerinden bir hata aldı veya hiç cevap almadı, bu durumda buna göre bu TracePoint silme mekanizması arka planda çalışıyor.
  • Diyelim ki belirtilen microservislere bağlantı kurdu ozamanda rengi değişerek mora dönüşüyor.

Bu tür optimistic update işleri UI’da çok ihtiyac olan konular. Ekranda sürekli Loading statüsleri göstermektense basit ve ufak güncellemelerde Optimistic Update kullanarak, müşterilerinize daha iyi bir UIX deneyimi sunabilirsiniz.

  • Bir Flag Enable/Disable Etme
  • Bir Bileşeni Gösterme/Gizleme Config Güncelleme
  • Bir Elemanı Silme veya Ekleme
React Query Optimistic Update Ele Alınması

E. Background Refetch

Özellikle arkaplanda fetch işleminin 1 saniye aralıklar ile yapılıp, değişim durumlarının UI bileşenlerine yansıtılması isteniyorsa aşağıdaki gibi useQuery verilen obj içerisinde refetchInterval parametresi geçirilerek bu işlem gerçekleştirilebilir.

React Query Refetch Intervals

Örneğin bir elemanın üzerine geldiğinde o elemanın Backend tekrar çağrılmasını istemek kısmını queryCache üzerinden gerçekleştirebilirsiniz.

React Query , queryCache kullanımı

Not: Son olarak React Query yapısını Redux yapısı ile birlikte kullanmak isterseniz Redux Toolkit benzer özelliklerde RTK Query isimli bir kütüphanesi bulunuyor. Bu kütüphaneyi kullanabilirsiniz.

Referanslar

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki(ürün ve kütüphaneler) diğer yazılara erişmek için bu linke tıklayabilirsiniz.

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

--

--