React Query (TanStack Query) ile Modern Veri Çekme ve Yönetimi: Uygulamalarınızı Süper Şarj Edin

Modern web uygulamaları, sadece karmaşık kullanıcı arayüzleri sunmakla kalmıyor, aynı zamanda sürekli güncellenen ve dinamikleşen verilerle de başa çıkmak zorunda kalıyor. Geleneksel React uygulamalarında, sunucu tarafı verilerini yönetmek (çekme, önbellekleme, senkronizasyon, güncelleme, hata yönetimi) genellikle boilerplate kod yığınına, race condition'lara ve tutarsız kullanıcı deneyimlerine yol açabiliyor. Frontend geliştiricileri olarak, bu süreçlerin getirdiği yükün farkındayız.
Benim geliştirme tecrübelerimde, özellikle büyük ölçekli ve veri odaklı React projelerinde, bu problemleri zarif ve etkili bir şekilde çözen bir araca duyulan ihtiyacı defalarca hissettim. İşte bu noktada React Query (şimdiki adıyla TanStack Query) devreye giriyor. React Query, sunucu durumunu yönetmek için geliştirilmiş, güçlü, esnek ve oldukça popüler bir kütüphanedir. Amacı, istemci tarafı state yönetiminden farklı olarak, uzak sunuculardan gelen verileri React uygulamanızda "sunucu durumu" olarak ele almaktır. Bu yazıda, React Query'nin ne olduğunu, neden bu kadar önemli olduğunu ve onu uygulamalarınızda nasıl kullanarak performans ve geliştirici deneyimini (DX) zirveye taşıyabileceğinizi detaylı bir şekilde inceleyeceğiz.
Neden React Query (TanStack Query)? Sunucu Durumu Yönetimine Yeni Bir Bakış
React, bileşenlerin durumunu yönetmek için harika bir kütüphane olsa da, "sunucu durumu" (server state) yönetimi için doğrudan bir çözüm sunmaz. Sunucu durumu; ağ üzerinden çekilen, eşzamansız olarak güncellenen, farklı istemciler tarafından değiştirilebilen ve genellikle uygulama dışındaki bir kaynakta (veritabanı) depolanan veridir. Bu tür veriler, istemci durumu (UI state) gibi anlık ve doğrudan kontrol edilebilir değildir.
Geleneksel Yaklaşımların Zorlukları
- Manuel Önbellekleme: Veriyi manuel olarak önbelleklemek ve güncel tutmak karmaşıktır.
- Veri Senkronizasyonu: Uygulama ve sunucu arasındaki verinin tutarlılığını sağlamak zordur.
- Tekrarlayan İstekler: Aynı veri için birden fazla bileşenden gelen gereksiz istekler performansı düşürür.
- Hata Yönetimi ve Yeniden Deneme: Ağ hataları, yükleme durumları ve otomatik yeniden denemeler için özel kod yazmak gerekir.
- UI Durum Yönetimi: Yükleniyor, hata, başarı gibi durumları her bileşende ayrı ayrı yönetmek yorucudur.
React Query, tüm bu zorlukları otomatikleştirerek ve geliştiriciye hazır hook'lar sunarak ortadan kaldırır. Tıpkı daha önce Appexa React Geliştirme Süreçlerinizi Işık Hızına Çıkarın yazısında değindiğim gibi, tekrarlayan kodların önüne geçmek ve geliştirme hızını artırmak, modern kütüphanelerin temel hedeflerinden biridir. React Query de bu felsefeyi sunucu durumu özelinde benimser.

React Query'nin Süper Güçleri ve Temel Avantajları
React Query'yi kullanmak, uygulamanıza ve geliştirme sürecinize birçok önemli avantaj sağlar:
- Otomatik Önbellekleme (Caching): Sunucudan çekilen verileri otomatik olarak önbelleğe alır. Aynı sorgu tekrar yapıldığında, veri önbellekten hemen sunulur ve arka planda güncel veri için bir istek daha atılır (stale-while-revalidate). Bu, anında yanıt veren bir kullanıcı deneyimi sağlar.
- Veri Güncelliği (Stale-While-Revalidate): Varsayılan olarak, verileri "stale" (eski) kabul eder ve arka planda yeni veri çekmeye çalışırken önbellekteki eski veriyi sunar. Bu, uygulamaların her zaman hızlı hissetmesini sağlar.
- Yükleme, Hata ve Boş Durum Yönetimi:
isLoading,isError,isSuccess,datagibi durumları hazır olarak sunar, böylece her veri çekme işlemi için manuel olarak bu state'leri yönetmek zorunda kalmazsınız. - Otomatik Yeniden Deneme (Retries): Ağ istekleri başarısız olduğunda, yapılandırılabilir bir gecikmeyle otomatik olarak yeniden deneme yapar.
- Tekrarlayan İsteklerin Birleştirilmesi (Deduplication): Aynı veri için aynı anda yapılan birden fazla isteği tek bir istekle birleştirerek sunucu yükünü azaltır ve performansı artırır.
- Garbage Collection: Artık kullanılmayan veya aktif olarak dinlenmeyen verileri önbellekten otomatik olarak temizler.
- Harika Geliştirici Deneyimi (DX): Sezgisel hook tabanlı API'si, güçlü DevTools'ları ve kapsamlı dokümantasyonu sayesinde geliştiricilerin hayatını kolaylaştırır. Derinlemesine React Hooks yazımda bahsettiğim gibi, custom hook'lar React geliştirmeyi ne kadar kolaylaştırıyorsa, React Query de benzer bir etki yaratır.
- Ön-bellekleme ve Arka Plan Güncellemesi: Kullanıcının ekrana baktığı an, veri güncel olmasa bile anında gösterilir. Arka planda veri güncellenirken, kullanıcı arayüzü takılmaz.
React Query'nin Temel Taşları: QueryClient, useQuery ve Query Keys
React Query ile çalışırken, anlamanız gereken birkaç temel yapı taşı vardır:
1. QueryClient
Uygulamanızın tüm React Query mantığını (önbellekleme, sorgu yönetimini, mutasyonları vb.) yöneten merkezi bir beyindir. Genellikle uygulamanızın en üst düzeyinde tanımlanır ve bir QueryClientProvider aracılığıyla React bileşen ağacına sağlanır.
2. useQuery Hook'u
Veri çekme işlemleri için kullanılan ana hook'tur. Bir sorgu anahtarı (Query Key) ve bir veri çekme fonksiyonu (Query Function) alır. Verinin yüklenme durumunu, hata durumunu ve çekilen veriyi döndürür.
3. Query Keys (Sorgu Anahtarları)
React Query'nin önbellekleme mekanizmasının kalbidir. Her sorguyu benzersiz bir şekilde tanımlamak için kullanılır. Dizi formatında olması önerilir ve genellikle ilk öğe çekilen kaynağın adını, sonraki öğeler ise parametreleri içerir (örneğin, ['todos', todoId]).
React Query ile Basit Bir Uygulama Örneği
Şimdi React Query'yi basit bir senaryoda nasıl kullanabileceğimize dair pratik bir örneğe göz atalım.
Adım 1: Kurulum
npm install @tanstack/react-queryAdım 2: QueryClient'ı Ayarlayın (src/main.jsx veya src/App.jsx)
import React from 'react';
import ReactDOM from 'react-dom/client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import App from './App';
import './index.css';
const queryClient = new QueryClient();
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>,
);
Adım 3: Veri Çekme (src/App.jsx)
Basit bir API'den kullanıcı listesi çekelim.
import { useQuery } from '@tanstack/react-query';
async function fetchUsers() {
const res = await fetch('https://jsonplaceholder.typicode.com/users');
if (!res.ok) {
throw new Error('Kullanıcılar yüklenirken bir hata oluştu.');
}
return res.json();
}
function UsersList() {
const { data: users, isLoading, isError, error } = useQuery({
queryKey: ['users'], // Benzersiz sorgu anahtarı
queryFn: fetchUsers, // Veri çekme fonksiyonu
staleTime: 5 * 60 * 1000, // Veri 5 dakika boyunca 'fresh' kalır
});
if (isLoading) return <div>Kullanıcılar yükleniyor...</div>;
if (isError) return <div>Hata oluştu: {error.message}</div>;
return (
<div>
<h2>Kullanıcılar</h2>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name} ({user.email})</li>
))}
</ul>
</div>
);
}
function App() {
return (
<div className="App">
<h1>React Query ile Veri Yönetimi</h1>
<UsersList />
</div>
);
}
export default App;
Yukarıdaki örnekte, useQuery hook'u sayesinde manuel olarak yükleniyor, hata veya veri durumlarını yönetmek zorunda kalmadık. React Query, bu işleri bizim için otomatik olarak halleder.

Veri Güncelleme: useMutation ile Optimistik Güncellemeler
Veri çekme kadar, veriyi sunucuda güncellemek de önemlidir. useMutation hook'u, sunucu tarafında CREATE, UPDATE, DELETE işlemleri için kullanılır. Özellikle "optimistik güncellemeler" (optimistic updates) sayesinde kullanıcı deneyimini çok daha akıcı hale getirebiliriz.
Optimistik Güncelleme Örneği: Bir Todo Öğesini Tamamlama
import React from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
// Mevcut Todo'ları çeken fonksiyon
async function fetchTodos() {
const res = await fetch('https://jsonplaceholder.typicode.com/todos?_limit=5');
if (!res.ok) throw new Error('Todo\'lar yüklenirken hata oluştu.');
return res.json();
}
// Bir Todo öğesini güncelleyen fonksiyon
async function updateTodoStatus(todoId, newStatus) {
const res = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId}`, {
method: 'PATCH',
body: JSON.stringify({ completed: newStatus }),
headers: { 'Content-type': 'application/json; charset=UTF-8' },
});
if (!res.ok) throw new Error('Todo güncellenemedi.');
return res.json();
}
function TodoList() {
const queryClient = useQueryClient();
const { data: todos, isLoading, isError, error } = useQuery({
queryKey: ['todos'],
queryFn: fetchTodos,
});
const updateTodoMutation = useMutation({
mutationFn: ({ todoId, newStatus }) => updateTodoStatus(todoId, newStatus),
// Optimistik güncelleme!
onMutate: async (newTodo) => {
// Aktif tüm 'todos' sorgularını iptal et, çakışmayı önle
await queryClient.cancelQueries({ queryKey: ['todos'] });
// Mevcut veriyi al
const previousTodos = queryClient.getQueryData(['todos']);
// Önbelleği anında güncelle (optimistik)
queryClient.setQueryData(['todos'], (oldTodos) => {
return oldTodos?.map((todo) =>
todo.id === newTodo.todoId ? { ...todo, completed: newTodo.newStatus } : todo
);
});
// Bir önceki veriyi context olarak döndür, hata durumunda geri alabilmek için
return { previousTodos };
},
onError: (err, newTodo, context) => {
// Hata olursa, önbelleği önceki duruma geri al
queryClient.setQueryData(['todos'], context.previousTodos);
console.error('Optimistik güncelleme başarısız oldu:', err);
},
onSettled: () => {
// İşlem bittiğinde (başarılı/hata), 'todos' sorgusunu geçersiz kıl ve yeniden çek
queryClient.invalidateQueries({ queryKey: ['todos'] });
},
});
if (isLoading) return <div>Todo\'lar yükleniyor...</div>;
if (isError) return <div>Hata oluştu: {error.message}</div>;
return (
<div>
<h2>Yapılacaklar Listesi</h2>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
<input
type="checkbox"
checked={todo.completed}
onChange={() => {
updateTodoMutation.mutate({ todoId: todo.id, newStatus: !todo.completed });
}}
disabled={updateTodoMutation.isLoading}
/>
<span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>
{todo.title}
</span>
</li>
))}
</ul>
{updateTodoMutation.isLoading && <p>Güncelleniyor...</p>}
{updateTodoMutation.isError && <p style={{ color: 'red' }}>Güncelleme başarısız!</p>}
</div>
);
}
export default TodoList;
onMutate fonksiyonu, asıl sunucu isteği yapılmadan hemen önce çalışır. Bu sayede, UI'yı anında güncelleyerek kullanıcıya kesintisiz bir deneyim sunabiliriz. Eğer sunucu isteği başarısız olursa (onError), context içinde sakladığımız previousTodos verisi ile UI'yı eski haline döndürerek tutarlılığı sağlarız. Son olarak, onSettled ile isteğin durumu ne olursa olsun önbelleği geçersiz kılarak verilerin yeniden çekilmesini ve tamamen güncel olmasını garanti ederiz. Bu, kullanıcı için anında geri bildirim sağlayan, sağlam bir yaklaşımdır. Daha geniş ölçekli ve kritik API etkileşimlerinde, backend tarafında Node.js ile Ölçeklenebilir Mikroservisler kurarak veya MongoDB ile Veri Optimizasyonu yaparak tüm ekosistemin performansını artırmak mümkündür.
Sonuç
React Query (TanStack Query), modern React uygulamalarında sunucu tarafı verilerini yönetme biçimimizi kökten değiştiren bir kütüphanedir. Geleneksel yaklaşımların getirdiği karmaşıklığı ortadan kaldırırken, geliştiricilere güçlü önbellekleme, otomatik senkronizasyon, hata yönetimi ve optimistik güncellemeler gibi paha biçilmez özellikler sunar.
Eğer siz de React uygulamalarınızın daha performanslı, daha kullanıcı dostu ve daha az boilerplate kodla geliştirilmesini istiyorsanız, React Query'ye mutlaka bir şans vermelisiniz. Kullanıcılarınız anında tepki veren arayüzlere bayılacak, siz de sunucu durumu yönetimiyle uğraşmak yerine uygulamanızın asıl iş mantığına odaklanabileceksiniz.
Uygulamalarınızı React Query ile süper şarj etmek sadece bir başlangıç. Unutmayın, en iyi geliştirici, sorunları doğru analiz edip en uygun çözümü (ki bu bazen React Query gibi bir kütüphane olabilir) uygulayabilen geliştiricidir. Eğer aklınıza takılan sorular olursa veya bu konularda daha derinlemesine bilgi almak isterseniz, bana ismailyagci371@gmail.com adresinden veya sosyal medya kanallarından (İsmail YAĞCI) ulaşabilirsiniz. Sağlıklı ve başarılı kodlamalar dilerim!
Orijinal yazı: https://ismailyagci.com/articles/react-query-tanstack-query-ile-modern-veri-cekme-ve-yonetimi-uygulamalarinizi-super-sarj-edin
Yorumlar
Yorum Gönder