Katılım
4 Şubat 2024
Mesajlar
3.916
Makaleler
7
Çözümler
77
Beğeniler
6.444
Bu gönderi bilgisayar kullanmayı bilen, okuduğunu leb demeden anlayan, React ve JSX bilgisi de olan JavaScript web programcılarına yöneliktir.


Sorunsuz state management için Redux gibi şeyleri hiç kullanmıyorum. Sizi Valtio ile tanıştırmak istiyorum.

NextJS projemde (React de olur) src klasöründe bir state.js dosyası.
JavaScript:
import { proxy } from "valtio";

const state = proxy({
  application: false,
  authenticated: false,
  offering: false,
  user: {},
});

export { state };

Herhangi bir bileşende veya sayfada doğrudan referans:
JavaScript:
import { state } from "@/state";

State elemanlarını herhangi bir yerde herhangi bir şekilde mutate etmek.

JavaScript:
state.sidebar = false;
state.user = {
    username: "test"
}

Snapshot almak, aka değerleri görüntülemek değişikliklere abone olmak ve anlık state yenilenmesi ;)

JavaScript:
import { proxy, useSnapshot } from "valtio";

//Component fonksiyonu içinde yapacaksın bunu:
const snap = useSnapshot(state);

Sonra da bu snapshot'a erişim ve abonelik:

JavaScript:
  useEffect(() => {
    if (snap.user == {}) {
      return;
    }
    console.log("Giriş yapan kullanıcı: ", snap.user.username);
  }, [snap.user]);

Canlı gör:


@brkdnmz sen Zustand kullanıyordun. Bunu da bir incele ;)
 
Son düzenleme:
Bu kütüphanenin geliştiricisi de Zustand'inki gibi Poimandres'ten Daishi abimizmiş. Sayesinde React için harika state yönetim çözümleri var elimizde. Zustand, tüm kütüphaneler içinde favorilerim arasındadır kesinlikle.

Daishi, burada Zustand ve Valtio arasındaki temel farkları özetlemiş:
  • Zustand, state için değiştirilemezliği benimserken Valtio tam tersi şekilde değiştirilebilirliği benimsiyormuş yani immutability vs. mutability söz konusu.
  • Render'ın ne zaman tetiklenmesi gerektiğini Valtio, kullanılan property'lere göre kendisi hallediyormuş. Bunu beğendim. Zustand'de işler biraz daha manuel.
Valtio, değiştirilebilirliği JavaScript'teki Proxy ile sağlıyormuş. Benim tam hakim olmadığım hatta neredeyse hiç hakim olmadığım bir konu. Şimdiye kadar tek yaptığım, büyülenmek oldu.


Zustand'i de Valtio gibi kullanmak mümkün aslında, ben fark etmemiştim de Zustand'in Immer middleware'ı Valtio'daki değiştirilebilirliği mümkün kılıyor, tabii ki yine Proxy ile. Daishi de burada buna değinmiş ve Zustand + Immer kombinasyonunu kullananlara -mesela ben- direkt Valtio'yu kullanmayı önermiş. Ben, söz konusu kombinasyonu "derin" nesneler (deeply nested) için kullanmaya başlamıştım. Sonra bir baktım kullanımı çok rahat, "Neden her yerde Immer kullanmayayım ki?" deyip her yerde kullanmaya başlamıştım.

Valtio, denemeye kesinlikle değer bir kütüphaneye benziyor. Sağladığı avantajlar az değilmiş.



Sonra da bu snapshot'a erişim ve abonelik:

JavaScript:
useEffect(() => {
  if (snap.user == {}) {
    return;
  }
  console.log("Giriş yapan kullanıcı: ", snap.user.username);
}, [snap.user]);

if(false) : )
 
Hö? Boş obje olup olmadığını kontrol ediyor işte, yanlış bir şey mi yaptım? :) Object.values(obj).length == 0 mu yapmalıydım? 🤔

Adres kontrolü yapıldığı için yeni oluşturulan boş objeyle karşılaştırma sonucu kesin false gelecek. : P Konsolda deneyebilirsiniz, en kolay yolu o olur galiba.

Object.values(obj).length == 0 gayet güzel duruyor. !("username" in snap.user) falan da yapılabilir. İki yerine üç eşittir de olsa tam olacak, bu örnekte pek zararı yok da yine de... : ))
 
Adres kontrolü yapıldığı için yeni oluşturulan boş objeyle karşılaştırma sonucu kesin false gelecek. : P Konsolda deneyebilirsiniz, en kolay yolu o olur galiba.
JavaScript:
state.user = {
    username: "test"
}

Yok işte burada oluşturulduysa dolu obje oluyor. useEffect'e dependency olarak koyduğum için de biliyorsun zaten muhabbeti.

Bu harika zaten. ♥
 
Yok işte burada oluşturulduysa dolu obje oluyor. useEffect'e dependency olarak koyduğum için de biliyorsun zaten muhabbeti.

Durumu biraz daha açayım:

[CODE lang="javascript" title="Sorunlu karşılaştırma"]if (snap.user == {}) {
return;
}[/CODE]

Burada snap.user ile satır içinde oluşturulan {} objesinin adresleri kesinlikle farklı olacağı için snap.user == {} ifadesinin değeri her zaman false gelecektir. İki eşittirden şüphelendiğim için konsolda da denedim, dediğim durum yaşandı:

1722300484037.webp

Olay boş obje olması değil de adresleri farklı iki objeyi direkt == / === ile karşılaştırmak.