REACT STATE MANAGEMENT
Hangi Client State Management Yöntemi’ni Kullanmalıyım ? useState, useContext, redux, zustand, jotai, …
Bu yazıda Client State Management için hangi yöntemleri kullanabilirim üzerine araştırma yaptım. (useState, useContext, redux, zustand, jotai, …) avantajı, dezavantajı için küçük bir deneme ortamı oluşturup bunun üzerinde denemeler yaptım.
Farklı State Management ortamlarını deneyebilmek için kendime bir playground yani oyun alanı oluşturma gerekiyordu. Bu oyun alanında bir bileşen olsun örnegin bir counter bileşenimiz olsun. Bu bileşen 2 kısımdan oluşsun.
- Bir Düğme ve
- Bir Gösterge.
Bu bileşeni kullanarak ayrı bir düzen oluşturmak istiyorum. Yani hiyerarşik olarak birbirinden farklı uzak düğümler altında olsunki veri taşımak için yaptığımız işlemlere, ve bunların etkilediği bileşenleri inceleyebilelim.
Burada bizi ilgilendiren State iletişimi olan sadece Inc ve ValDisp bileşeni onun dışında yer alan Main, Counter, CompA, CompB, CompC Layout ile ilgili State ile hiç ilgisi olmayan nesneler diyebiliriz.
Biraz daha durumu karmaşıklaştıralım ve 2 tane Counter kullanarak yapalım. State daha bağımsız bir şekilde çalışabildiğini göstermiş olalım. Sonuçta aşağıdaki gibi bir görsel ortaya çıkıyor..
Deneme Ortamları
Şimdi gelelim deneme ortamlara,
- Props Drilling Örneği
- Context Örneği, Context ile ilgili blog yazısı
- Zustand Örneği, Zustand ile ilgili blog yazısı
- Jotai Örneği, Jotai ile ilgili blog yazısı
- Redux Örneği, Redux ile ilgili blog yazısı
- Signals Örneği , Signals ile ilgili blog yazısı
Props Drilling Yöntemi (useState)
Props Drilling yöntemide Counter1 ve Counter 2 State Lift State Up yaparak en üstte bulunan StatePropDrillingPage bileşeni içerisinde tutacağız. Props drilling yöntemi ile tüm elemanlarına ve onun çoçuk elemanlarına transfer etmisini sağlayacağız.
function StatePropDrillingPage() {
const [count1, setCount1] = useState(0);
const [count2, setCount2] = useState(0);
const renderDemo = () => {
return <CompMain count1={count1} count2={count2} onClick1={() => setCount1(count1 + 1)} onClick2={() => setCount2(count2 + 1)} />;
};
tabi bu yapının zahmetli ve problemli yanları vardır.
- Tüm Props Delegate Etmek İhtiyacı: Props sayısı çok fazla ise alt bileşene tümden delegate etmek için {…props} şeklinde veya arada sizin eklemeleriniz varsa {…props, x:x} şeklinde bileşininiz ile ilgili olmayan ama alt bileşene delegate etme kodlarını barındırmanız gerekiyor. Ama props içeriği açılmadığı için kod çok fazla karışık değil.
- Propsları Parça Parça Çokça Delegate Etme: Props sayısı çok fazla bazılarını aşağıya delatate etmeniz gerekiyor ama yinede props sayısı çok fazla ise <A x1 x2 x3 … xn> <B y1 y2 y3… xn> gibi bileşenler oluşturmanız gerekirki bu sefer ara sınıflardaki bu parçalanmaları yapan bileşen Dummy bir Layout vs.. yerine bir Manager gibi davranmış olur.
- Props Ulaştırmak İstediğiniz Bileşen Ağaç Hiyerarşisinde Çok Aşağıda İse: Yani bizim bu propsları bir çok bileşen atlatmamız gereken bir durumda her bileşendeki kod daha kırılgan yani değişime açık hale geliyor.
SOLID yazımızdaki O harfine karşılık gelen Open-Closed Principle uymamış oluyoruz.
O. Open-Closed Principle:
Sınıflarınızın genişlemeye açık , değişime kapalı olmasıdır. Özetle amacı sisteme yeni bir fonksiyon eklemek istediğimiz zaman bunu mevcut sınıflara dokunmandan AbstractClass/Interface extend ederek gerçekleştirebilmektir. Bu sayede yeni özellik eklemek için mevcut sınıfların güncellenmesine gerek kalmaz.
RENDERİNG
Biz Frontend geliştiriciler açısından bir problem de Rendering giren bileşenlerin oluşturduğu performans sorunu bu yapının nasıl bir etkisi oluyor derseniz aşağıdaki örneği inceleyebilirsiniz.
https://onurdayibasi.dev/state-props-drilling
Bizim bu yöntemde Counter1 içerisindeki Inc Düğmesine bastıgımızda kendisine Main’den props ile geçirilmiş callback onClick tetikler..
export const IncBtn = props => <button onClick={props.onClick}>Inc</button>
Bunun sonucunda Main üzerindeki count1 state güncellenir . Bu sırası ile
- Main → Counter1 → Counter2 → CompA → CompB → C1 → C2 bileşenlerinin çağrımını yapıp sadece C1deki value arttırmış olduk.
Bu nerdeyse tüm bileşenlerin render edilmesi ile sonuçlanmış oldu. Bu kısmı biraz optimize edebiliriz
- Analyses on Re-render of React Component — 1
- Analyses on Re-render of React Components — 3 (useMemo)
- Analyses on Re-render of React Components — 2 (useCallback)
Ama Main -> CompA -> CompB -> C1 hiyerarşisindeki rendering olmadan en alttaki bileşene props ulaştıramayacağımız için BU MİMARİ’nin hem bize çok Optimizazyon işi çıkarıyor, hemde sadece değişen kısımların Render edilmesinide sağlayamıyor.
Not: Bir sonraki yazımızda Context ile ilgili yaptığımız playground ortamını açıklamaya çalışacağım.
Okumaya Devam Et 😃
Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke tıklayabilirsiniz.