React Query ile Supabase Verilerini Akıllıca Cache'leme

Web uygulamanız her sayfa geçişinde veritabanına sorgu atıyor mu? React Query ile Supabase verilerini nasıl cache'leyeceğinizi, gereksiz API çağrılarını nasıl azaltacağınızı basitçe anlattık.

Sorun: Her Tıklamada Veritabanına Gidiliyor

Kullanıcı stok sayfasını açtı — veri çekildi. Satış sayfasına geçti. Tekrar stok sayfasına döndü — aynı veri tekrar çekildi. 5 dakika içinde hiçbir şey değişmedi ama 10 kez veritabanına sorgu gitti.

50 aktif kullanıcınız varsa bu durum:

50 kullanıcı × dakikada 3 sayfa geçişi × 5 sorgu = 750 sorgu/dakika

Hem yavaş, hem gereksiz, hem de Supabase kotanızı yer.

Çözüm: React Query (TanStack Query)

React Query, veritabanından çektiğiniz veriyi belirli bir süre hafızada tutar. Bu süre içinde aynı veri istenirse veritabanına gitmez, hafızadan döner.

İlk açılış:  Veritabanı → Veri geldi → Hafızada sakla (5 dk)
2. açılış:   Hafızadan → Anında geldi ✅ (0 ms)
5 dk sonra:  Hafıza "bayat" → Arka planda günceller

Temel Kullanım

import { useQuery } from '@tanstack/react-query';

function StokSayfasi() {
  const { data: stoklar, isLoading } = useQuery({
    queryKey: ['stok-listesi'],           // Bu verinin ismi
    queryFn: () => supabase               // Nasıl çekileceği
      .from('v3_stock')
      .select('*')
      .then(res => res.data),
    staleTime: 5 * 60 * 1000,            // 5 dakika taze say
  });

  if (isLoading) return <p>Yükleniyor...</p>;

  return (
    <table>
      {stoklar?.map(stok => (
        <tr key={stok.id}>
          <td>{stok.stok_adi}</td>
          <td>{stok.miktar}</td>
        </tr>
      ))}
    </table>
  );
}

staleTime: 5 dakika demek: “Bu veriyi 5 dakika boyunca taze kabul et. Bu sürede başka sayfalara gidip gelse bile veritabanına gitme.”

staleTime Ne Olmalı?

Her veri aynı sıklıkta değişmez. Buna göre cache süresini ayarlayın:

Veri TipistaleTimeNeden
Sipariş durumu1 dakikaSık değişir
Stok listesi5 dakikaOrta sıklıkta
Şube listesi30 dakikaNadiren değişir
Birim listesi1 saatNeredeyse hiç değişmez
// Projenizde kullanabileceğiniz sabitler
const CACHE_SURELERI = {
  HIZLI: 1 * 60 * 1000,     // 1 dk — sipariş, anlık veriler
  NORMAL: 5 * 60 * 1000,    // 5 dk — genel listeler
  YAVAS: 30 * 60 * 1000,    // 30 dk — nadiren değişenler
  SABIT: 60 * 60 * 1000,    // 1 saat — birim, kategori listesi
};

Veri Güncelleyince Cache’i Temizleme

Kullanıcı stok miktarını güncellediğinde, eski cache’i temizlemeniz gerekir:

import { useMutation, useQueryClient } from '@tanstack/react-query';

function StokGuncelle() {
  const queryClient = useQueryClient();

  const guncelle = useMutation({
    mutationFn: async (yeniMiktar) => {
      await supabase
        .from('v3_stock')
        .update({ miktar: yeniMiktar.miktar })
        .eq('stok_kodu', yeniMiktar.stokKodu);
    },
    onSuccess: () => {
      // Güncelleme başarılı → stok cache'ini temizle
      queryClient.invalidateQueries({ queryKey: ['stok-listesi'] });
      // → Otomatik olarak yeni veriyi çeker
    },
  });
}

invalidateQueries demeniz yeterli — React Query otomatik olarak yeni veriyi çekip ekranı günceller.

Sonuç: Gereksiz Sorgular %90+ Azalır

Cache öncesi:  750 sorgu/dakika
Cache sonrası:  ~50 sorgu/dakika  (%93 azalma)

Kullanıcı hiçbir fark hissetmez — hatta sayfa geçişleri anlık olur çünkü veri zaten hazırdır.

Daha İleri Gitmek İsteyenler İçin

Bu temel cache stratejisi çoğu proje için yeterlidir. Ama ölçek büyüdükçe:

  • Optimistic Updates: Kullanıcı “Kaydet” dediğinde ekran hemen güncellenir, arka planda veritabanına yazılır
  • İki sekmede çalışma: Aynı kullanıcı iki tarayıcı sekmesinde çalışıyorsa cache senkronizasyonu
  • İnternet kesilirse: Offline sırasında yapılan değişiklikleri sıraya koyma

Biz 40+ farklı veri sorgusunu koordine eden bir yapıda bu sorunların hepsini çözdük. İhtiyacınız olursa deneyimimizden faydalanabilirsiniz.


Bu yazı AstaFlow Case Study serisinin bir parçasıdır.