Blog

React Query Patterns (Production Notes)

Cache, invalidate, optimistic update, server-state sınırları ve gerçek dünya performans notları.

6 dkMustafa Ulutaş

TanStack Query (React Query) doğru kullanıldığında sunucu durumu yönetimini köklü biçimde basitleştirir. Ancak üretim ortamında karşılaşılan senaryolar belgelerde tam anlatılmaz. Gerçek projelerde öğrendiğim pattern'leri paylaşıyorum.

Cache Stratejisi

Her veri türü için farklı staleTime değeri kullanın. Kullanıcı profili sık değişmez; ürün listesi değişebilir.

query-config.ts
TypeScript
export const queryConfig = {
  // Neredeyse hiç değişmeyen veriler (referans data)
  static: {
    staleTime: 60 * 60 * 1000, // 1 saat
    gcTime: 24 * 60 * 60 * 1000,
  },
  // Kullanıcı profili, ayarlar
  user: {
    staleTime: 5 * 60 * 1000,  // 5 dk
    gcTime: 30 * 60 * 1000,
  },
  // Gerçek zamanlı veriler
  realtime: {
    staleTime: 0,
    refetchInterval: 30_000,
  },
} satisfies Record<string, Parameters<typeof useQuery>[0]>;

Optimistic Updates

UI'ı anında güncelleyin, hata durumunda geri alın. Kullanıcı deneyimini önemli ölçüde iyileştirir.

use-toggle-like.ts
TypeScript
export function useToggleLike(postId: string) {
  const queryClient = useQueryClient();
  const key = ["post", postId];

  return useMutation({
    mutationFn: (liked: boolean) => api.toggleLike(postId, liked),
    onMutate: async (liked) => {
      await queryClient.cancelQueries({ queryKey: key });
      const prev = queryClient.getQueryData<Post>(key);

      queryClient.setQueryData<Post>(key, (old) =>
        old ? { ...old, liked, likeCount: old.likeCount + (liked ? 1 : -1) } : old
      );

      return { prev };
    },
    onError: (_, __, ctx) => {
      // Hata durumunda geri al
      if (ctx?.prev) queryClient.setQueryData(key, ctx.prev);
    },
    onSettled: () => queryClient.invalidateQueries({ queryKey: key }),
  });
}

Server State Sınırları

React Query sadece sunucu durumu için. UI state (modal açık/kapalı, form state) için Zustand veya React state kullanın. İkisini karıştırmak bakım zorluğu yaratır.

Sık hata: onSuccess callback'inde başka mutation tetiklemek. Bunun yerine onSettled +invalidateQueries zinciri kullanın.

Doğru kullanılan TanStack Query, Redux veya Context tabanlı çözümlere kıyasla hem daha az boilerplate hem de daha iyi kullanıcı deneyimi sunar.

Mustafa Ulutaş
Full-Stack Software Engineer

Modern web deneyimleri, üretimde çalışan backend sistemleri ve performans odaklı ürün tasarımı üzerinde çalışıyorum.