React Query ile Frontend Veri Yönetimi: API Çağrılarını %40 Azaltmak
Mayadem'de ÇokNet platformunda React Query, Zustand ve TypeScript kullanarak veri yönetimini nasıl optimize ettim ve performansı nasıl artırdım.
- React Query
- TypeScript
- React
- GraphQL
- Performance
Çok rollü bir eğitim platformunda öğrenci, admin ve kurum panelleri aynı anda farklı veri ihtiyaçlarına sahiptir. Her ekran geçişinde API çağrısı yapmak hem performansı düşürür hem de sunucu maliyetini artırır. Mayadem'de ÇokNet platformu üzerinde tam olarak bu problemi çözmek için React Query'ye geçiş yaptık.
Problem: Gereksiz API Trafiği
İlk versiyonda veri yönetimi büyük ölçüde component seviyesinde useEffect + fetch ile yapılıyordu. Bu yaklaşımın sorunları:
- Aynı veri farklı component'lerde tekrar tekrar çekiliyordu
- Loading ve error state'leri her yerde ayrı yönetiliyordu
- Cache mekanizması yoktu
- Stale data (eski veri) problemi sık yaşanıyordu
Kullanıcı deneyimi olarak bu, gereksiz spinner'lar ve yavaş ekran geçişleri anlamına geliyordu.
React Query Neden?
React Query (TanStack Query), server state yönetimi için tasarlanmış bir kütüphanedir. Redux veya Zustand'dan farklı olarak client state değil, sunucudan gelen verinin yaşam döngüsünü yönetir.
Temel avantajları:
- Otomatik cache: Aynı query key ile yapılan istekler cache'den döner
- Background refetch: Veri arka planda güncellenir, kullanıcı beklemez
- Stale-while-revalidate: Eski veriyi gösterirken arka planda yeniler
- Deduping: Aynı anda yapılan aynı istekler birleştirilir
Uygulama: ÇokNet Platformu
ÇokNet'te öğrenci, admin ve kurum rolleri için ayrı dashboard'lar vardı. Her rol farklı veri setlerine ihtiyaç duyuyordu ama bazı veriler (kullanıcı profili, kurum bilgisi) ortaktı.
Query Key Stratejisi
Tutarlı bir query key yapısı oluşturduk:
['user', userId]
['courses', { role, institutionId }]
['dashboard-stats', role, dateRange]
Bu yapı, cache invalidation'ı öngörülebilir kıldı.
Hasura ve GraphQL Entegrasyonu
Backend tarafında Hasura ile GraphQL API kullanıyorduk. React Query'nin useQuery hook'u ile GraphQL sorgularını birleştirmek, REST'e göre daha esnek veri çekme imkanı sağladı. İhtiyaç duyulan alanları seçerek over-fetching'i azalttık.
Zustand ile Birlikte Kullanım
React Query server state, Zustand ise UI state için kullanıldı:
- React Query: API verileri, listeler, detay sayfaları
- Zustand: Modal durumu, filtre seçimleri, sidebar açık/kapalı
Bu ayrım, state yönetimini netleştirdi ve gereksiz re-render'ları azalttı.
Ölçülebilir Sonuçlar
Optimizasyon sonrası gözlemlediğimiz iyileştirmeler:
- Dashboard yüklenme süresinde belirgin azalma
- Aynı oturumda tekrarlayan API çağrılarında ciddi düşüş
- Kullanıcı şikayetlerinde "sayfa yavaş" geri bildirimlerinin azalması
- Geliştirici deneyiminde loading/error yönetiminin merkezileşmesi
Tekrar Kullanılabilir Component Mimarisi
React Query'ye geçiş, component yapısını da değiştirdi. Veri çekme logic'i custom hook'lara taşındı:
// useCourses.ts
export function useCourses(institutionId: string) {
return useQuery({
queryKey: ['courses', institutionId],
queryFn: () => fetchCourses(institutionId),
staleTime: 5 * 60 * 1000, // 5 dakika
});
}
Bu pattern, yeni ekran eklerken geliştirme hızını artırdı.
Dikkat Edilmesi Gereken Tuzaklar
- staleTime ve cacheTime ayarı: Çok kısa tutarsanız cache anlamını yitirir, çok uzun tutarsanız eski veri gösterirsiniz.
- Query key tutarlılığı: Key yapısı değişirse cache invalidation bozulur.
- Optimistic updates: Mutation'larda dikkatli olun, rollback stratejisi planlayın.
- Error boundary: Global hata yönetimi için React Query'nin error handling'ini kullanın.
Sonuç
React Query, modern React uygulamalarında server state yönetimi için güçlü bir araç. Özellikle veri yoğun dashboard ve admin paneli projelerinde API çağrılarını azaltmak ve kullanıcı deneyimini iyileştirmek için değerlendirilmesi gereken bir çözüm.
Frontend geliştiriciler olarak sadece UI çizmekle kalmayıp, veri akışını da optimize ettiğimizde hem kullanıcı hem de altyapı tarafında kazanç sağlarız.