ADR-010: State Management — Zustand + TanStack Query
| Durum | Kabul Edildi |
| Tarih | 2025-11 |
| Karar Veren | Güçlü Ceyhan |
Baglam
Zeus 2.0 frontend'inde iki farkli state kategorisi yonetilmelidir:
Server State (API verileri)
- Cihaz listesi, olcum verileri, alarm kayitlari, kullanici bilgileri
- Backend'den gelir, cache'lenir, periyodik olarak yenilenir
- Sayfalama, filtreleme, arama destegi
- Gercek zamanli guncelleme (WebSocket ile birlesik)
Client State (UI durumu)
- Sidebar acik/kapali, tema (dark/light), aktif kullanici oturumu
- Sadece frontend'de yasayan, backend'e gonderilmeyen veriler
- Sayfa gecislerinde korunmasi gereken durumlar
Bu iki state kategorisi farkli yasam dongusu ve guncelleme patterine sahiptir — tek bir state kutuphanesi ile yonetmek karmasikliga yol acar.
Karar
- Server state → TanStack Query v5 (
@tanstack/react-query) - Client state → Zustand v4
Kullanim Ornekleri
// Server state — TanStack Query
const { data: devices, isLoading } = useQuery({
queryKey: ['devices', tenantId],
queryFn: () => deviceService.getAll(tenantId),
staleTime: 30_000, // 30 saniye
refetchInterval: 60_000, // 1 dakikada bir yenile
});
// Mutation ornegi
const createDevice = useMutation({
mutationFn: deviceService.create,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['devices'] });
},
});
// Client state — Zustand
interface SidebarStore {
isOpen: boolean;
toggle: () => void;
}
const useSidebarStore = create<SidebarStore>((set) => ({
isOpen: true,
toggle: () => set((state) => ({ isOpen: !state.isOpen })),
}));
Alternatifler
Redux (+ RTK Query)
- Artilari: Olgun ekosistem, DevTools, Redux Toolkit ile modern API, RTK Query ile server state
- Eksileri: Boilerplate fazla (slice, reducer, action), store konfigurasyonu karmasik, ogrenme egrisi yuksek
- Red nedeni: Zeus 2.0'in 3 store'luk client state'i icin Redux asiri muhendislik
MobX
- Artilari: Reactive programlama, minimal boilerplate, class-based store'lar
- Eksileri: Proxy-based reaktivite debugging'i zorlastirabilir, server state yonetimi icin ek cozum gerekir
- Red nedeni: Server state (API verileri) icin cache/refetch mekanizmasi yok — ek kutuphane gerekir
SWR (Stale-While-Revalidate)
- Artilari: Basit API, Vercel ekosistemi (Next.js uyumu), kucuk bundle
- Eksileri: Mutation destegi TanStack Query kadar kapsamli degil, DevTools sinirli, sayfalama/infinite scroll destegi temel
- Red nedeni: Karmasik mutation senaryolari (optimistic update, rollback) ve gelismis cache yonetimi icin TanStack Query daha guclu
React Context + useReducer
- Artilari: Harici bagimliligi yok, React native cozum
- Eksileri: Gereksiz re-render riski (context degistiginde tum consumer'lar render olur), cache yonetimi manuel, boilerplate fazla
- Red nedeni: Performans sorunlari ve cache yonetimi eksikligi
Gerekce
Secilen kombinasyon su avantajlari sundu:
- TanStack Query — otomatik cache: Ayni veriyi birden fazla bilesen kullansa bile tek API cagrisi yapilir, sonuc cache'ten servis edilir
- TanStack Query — stale-while-revalidate: Eski veri aninda gosterilir, arka planda yenisi cekilir — kullanici beklemez
- TanStack Query — refetch stratejileri:
refetchOnWindowFocus,refetchInterval,refetchOnReconnect— gercek zamanli deneyim - TanStack Query — mutation + invalidation: Veri degistiginde ilgili sorgular otomatik yenilenir — tutarlilik garanti
- Zustand — minimal: 3 store (auth, sidebar, theme) — toplam ~50 satir kod
- Zustand — boilerplate yok: Redux'in slice/reducer/action uclüsü yerine tek fonksiyon
- TypeScript uyumu: Her iki kutuphane de TypeScript-first tasarimli — tip cıkarımı otomatik
- DevTools destegi: TanStack Query DevTools (sorgu durumu, cache goruntuleme) ve Zustand DevTools (store snapshot)
Sonuclar
Olumlu
- Server state ve client state birbirinden temiz sekilde ayrilmis — sorumluluklar net
- API verileri otomatik cache'leniyor — gereksiz network istekleri onleniyor
- Dashboard sayfasinda
refetchIntervalile olcum verileri otomatik guncelleniyor - Mutation sonrasi
invalidateQueriesile liste sayfasi aninda guncelleniyor - Zustand store'lari cok kucuk ve anlasilir — yeni gelistirici dakikalar icinde anlayabilir
- Bundle boyutu dusuk (TanStack Query: ~39KB, Zustand: ~3KB gzipped)
Olumsuz
- Iki farkli state kutuphanesi ogrenmek gerekli: Yeni gelen gelistirici hem TanStack Query hem Zustand API'sini ogrenmeli
- Sinir belirleme: "Bu veri server state mi client state mi?" sorusuna net cevap verilmeli — yanlis kategorize edilmis state bakimi zorlastirir
- DevTools bagimliligi: TanStack Query DevTools development build'de otomatik yuklenir — production'da devre disi birakilmali
- Cache invalidation karmasikligi: Iliskili veriler degistiginde (ornegin cihaz silindiginde hem cihaz listesi hem olcumler invalidate edilmeli) dikkatli yonetim gerekir