Bu yazıda, Next.js 15 ve Tanstack Query kullanarak nasıl daha verimli veri yönetimi yapabileceğinizi adım adım anlatacağım. Bu iki güçlü aracı birlikte kullanarak, hem sunucu hem de istemci tarafında verileri nasıl daha etkili bir şekilde çekebileceğinizi ve önbelleğe alabileceğinizi göstereceğim. Örnek olarak bir kampanya listesi uygulaması yapacağız.
Dosya Yapısı
Kodun düzenli ve okunabilir olması çok önemli. İşte benim önerdiğim dosya yapısı. Bu yapı, benim için modülerliği ve kodun daha rahat anlaşılmasını sağlamaya yardımcı oluyor.
src/
│
├── actions/ # Sunucu işlemleri
├── config/ # Genel ayarlar
├── app/ # Uygulama genel dosyaları
├── components/ # UI bileşenleri
├── constants/ # Sabitler (örneğin: query keys)
├── hooks/ # React hook'ları
└── views/ # Sayfa bileşenleri
Tanstack Query ve Axios Kurulumu
İlk adım olarak Tanstack Query ve Axios’u projeye ekleyelim:
Veri çekme işlemlerinde anahtarların (query keys) merkezi bir dosyada toplanması, ileride kodun sürdürülebilirliği açısından büyük kolaylık sağlar. Örneğin:
Dosya: constants/queryKeys.ts
export const QUERY_KEYS = {
CAMPAIGNS: "campaigns",
};
QueryClient Ayarları
Sunucu ve istemci tarafında aynı QueryClient
yapısını kullanmak için QueryClient
’i global bir dosyada tanımlıyoruz:
import {
QueryClient,
defaultShouldDehydrateQuery,
isServer,
} from "@tanstack/react-query";
function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000 * 5,
},
dehydrate: {
shouldDehydrateQuery: (query) =>
defaultShouldDehydrateQuery(query) ||
query.state.status === "pending",
},
},
});
}
let browserQueryClient: QueryClient | undefined = undefined;
export function getQueryClient() {
if (isServer) {
return makeQueryClient();
} else {
if (!browserQueryClient) browserQueryClient = makeQueryClient();
return browserQueryClient;
}
}
Tanstack Query’yi Global Olarak Kullanmak için Providers
Tanstack Query’yi tüm uygulamada erişilebilir hale getirmek için, Providers
bileşeni ile uygulamayı sarıyoruz.
"use client";
import { QueryClientProvider } from "@tanstack/react-query";
import { getQueryClient } from "./queryClient";
export default function Providers({ children }: { children: React.ReactNode }) {
const queryClient = getQueryClient();
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
);
}
Kampanya Verilerini Sunucudan Çekmek
Kampanya verilerini sunucudan çekip Tanstack Query ile önceden önbelleğe almak performansı artırır.
Dosya: actions/campaignsGET.ts
"use server";
import axios from "axios";
import { getQueryClient } from "@/config/queryClient";
import { QUERY_KEYS } from "@/constants/queryKeys";
const BASE_URL = "http://localhost:3000";
export async function fetchCampaigns() {
const response = await axios.get(`${BASE_URL}/api/campaigns`);
if (response.status !== 200) {
throw new Error("Kampanyalar yüklenirken bir hata oluştu");
}
return response.data;
}
export async function serverCampaignsGET() {
const queryClient = getQueryClient();
await queryClient.prefetchQuery({
queryKey: [QUERY_KEYS.CAMPAIGNS],
queryFn: fetchCampaigns,
});
return queryClient;
}
Layout Bileşeni ile React Query’yi Eklemek
Uygulamayı saran bir RootLayout
oluşturarak React Query özelliklerini global hale getiriyoruz.
Dosya: app/layout.tsx
import Providers from '@/config/providers';
export default function RootLayout({ children }) {
return
<html lang="tr">
<body>
<Providers>
{children}
</Providers>
</body>
</html>
);
}
Tanstack Query Hook ile Veri Çekmek
İstemci tarafında kampanya verilerini almak için özel bir hook yazıyoruz.
Dosya: hooks/api/campaign/useCampaignsGET.ts
"use client";
import { useQuery } from "@tanstack/react-query";
import { fetchCampaigns } from "@/actions/campaigns/campaignsGET";
import { QUERY_KEYS } from "@/constants/queryKeys";
export const useCampaignsGET = () => {
return useQuery({
queryKey: [QUERY_KEYS.CAMPAIGNS],
queryFn: fetchCampaigns,
});
};
Kampanya Listesi Sayfası
Sunucuda önceden çektiğimiz kampanya verilerini sayfa bileşenine bağlıyoruz. Bu şekilde istemci tarafında ekstra veri çekmeden hızlı bir şekilde sayfayı render edebiliriz.
import { dehydrate, HydrationBoundary } from '@tanstack/react-query';
import CampaignList from '@/components/CampaignList';
import { serverCampaignsGET } from '@/actions/campaignAllGET';
export default async function Page() {
const queryClient = await serverCampaignsGET();
const dehydratedState = dehydrate(queryClient);
return (
<HydrationBoundary state={dehydratedState}>
<CampaignList />
</Hydrate>
);
}
Kampanya Listeleme Bileşeni
Son olarak, kampanya listesini kullanıcıya gösteriyoruz:
Dosya: components/campaign/List.tsx
"use client";
import React from "react";
import { useCampaignsGET } from "@/hooks/api/campaign/useCampaignAllGET";
const CampaignList:React.FC<> = () => {
const { data, isLoading, error } = useCampaignsGET();
if (isLoading) return <div>Yükleniyor...</div>;
if (error) return <div>Bir hata oluştu: {error.message}</div>;
return (
<div>
<h1>Kampanya Listesi</h1>
<ul>
{data.map((campaign) => (
<li key={campaign.id}>{campaign.name}</li>
))}
</ul>
</div>
);
};
export default CampaignList;
Bu adımlarla, Next.js 15 ve Tanstack Query kullanarak veriyi hem istemci hem sunucu tarafında etkili bir şekilde yönetebiliriz. React Server Components, prefetching, ve Tanstack Query’nin güçlü önbellekleme stratejileri sayesinde uygulamalarınızı daha hızlı ve performanslı hale getirebilirsiniz.
Okuduğunuz için teşekkür ederim! Sonraki yazılarımda görüşmek üzere. 👋