MENU

Next.js 15 ve Tanstack Query ile Performanslı Veri Yönetimi

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.

December 7, 2024

Türkçe

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:

npm

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, // 5 dakika sonra yeniden çek
      },
      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";

// API isteği ile kampanya verilerini çekme
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;
}

// Sunucu tarafında kampanya verilerini çekme
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<> = () => {
  // Bu bileşen, sunucuda önceden fetch edilen verileri kullanır.
  // Client tarafında bir daha istek atılmayacak.
  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. 👋

Next.js

TanStack Query

React

Server Actions

İsmail Becit

Front-End Developer

HQ

Maslak Mah. AOS 55. Sok.
B Blok Apt. No: 4 / 542
Sarıyer / İstanbul 34475

R&D

Üniversite Mah. Sarıgül Sok.
No: 37 / 1 İç Kapı No: 91
Avcılar / İstanbul 34320

© 2024 - All rights reserved

HQ

Maslak Mah. AOS 55. Sok.
B Blok Apt. No: 4 / 542
Sarıyer / İstanbul 34475

R&D

Üniversite Mah. Sarıgül Sok.
No: 37 / 1 İç Kapı No: 91
Avcılar / İstanbul 34320

© 2024 - All rights reserved

HQ

Maslak Mah. AOS 55. Sok. B Blok Apt. No: 4 / 542
Sarıyer / İstanbul 34475

R&D

Üniversite Mah. Sarıgül Sok. No: 37 / 1 İç Kapı No: 91 Avcılar / İstanbul 34320

© 2024 - All rights reserved