Server hazırdır, indi interfeysi qoşmaq qalır. «Yüklənir» vəziyyətini və xətaları göstərmək, eyni sorğuları yüz dəfə göndərməmək və qeyd əlavə ediləndən sonra siyahını yeniləmək lazımdır. Bütün bunlara TanStack Query baxır, tRPC isə onu sizin router ilə — tam tiplərlə — səliqəli birləşdirir. Bu dərsdə müştərini Next.js App Router-ə qoşacağıq, məlumatı oxumağı və dəyişməyi, optimistik yeniləmələr etməyi və procedure-ləri birbaşa serverdə çağırmağı öyrənəcəyik.

İnteqrasiya necə qurulub

Birinci dərsdə procedure-ləri «birbaşa» çağırırdıq: trpc.note.list.query(). Bu, adi müştəridir — sorğu göndərib nəticəni qaytara bilir, amma keş və yüklənmə vəziyyəti haqqında heç nə bilmir. React üçün @trpc/tanstack-react-query paketi var və o, başqa cür işləyir: TanStack Query-ni əvəz etmir, onun üçün ayarlar hazırlayır.

Bənzətmə: tRPC sorğunun «reseptidir» (ünvan, giriş verilənləri, nəticənin tipi), TanStack Query isə reseptə görə hazırlayan «aşpazdır»: keşləyir, uğursuz olanda təkrarlayır, yüklənmə vəziyyətini göstərir. Reseptləri queryOptions() və mutationOptions() metodları qaytarır, aşpaza isə onu özünüz verirsiniz — adi useQuery və useMutation-a.

tRPC-dəTanStack Query-dəNə üçün
trpc.x.queryOptions()useQueryverilənlərin oxunması
trpc.x.mutationOptions()useMutationverilənlərin dəyişdirilməsi
trpc.x.queryFilter()invalidateQuerieskeşi sıfırlamaq ki, verilənlər yenidən yüklənsin
trpc.x.queryKey()getQueryData, setQueryDatakeşi əllə dəyişmək

Qoşulma: provider

İki obyekt yaratmaq lazımdır — TanStack Query müştərisi (QueryClient) və tRPC müştərisi — və onları provider-ə ötürmək. Hook-ları və provider-i createTRPCContext funksiyası yaradır:

tsx
// lib/trpc.tsx
'use client';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createTRPCClient, httpBatchLink } from '@trpc/client';
import { createTRPCContext } from '@trpc/tanstack-react-query';
import { useState } from 'react';
import type { AppRouter } from '@/server/routers/_app';

export const { TRPCProvider, useTRPC } = createTRPCContext<AppRouter>();

export function TRPCReactProvider(props: { children: React.ReactNode }) {
  const [queryClient] = useState(() => new QueryClient());
  const [trpcClient] = useState(() =>
    createTRPCClient<AppRouter>({
      links: [httpBatchLink({ url: '/api/trpc' })],
    }),
  );

  return (
    <QueryClientProvider client={queryClient}>
      <TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
        {props.children}
      </TRPCProvider>
    </QueryClientProvider>
  );
}

Burada vacib olanlar:

  • 'use client' məcburidir: provider və hook-lar yalnız müştəri komponentlərində işləyir.
  • createTRPCContext<AppRouter>() TRPCProvider və useTRPC hook-unu qaytarır. AppRouter tipi — serverin keçən dərsdə ixrac etdiyi həmin tipdir.
  • Hər iki müştəri useState(() => ...) ilə yaradılır ki, hər render-də yenidən yaranmasın: əks halda keş sıfırlanardı.
  • url route handler-dəki endpoint ilə üst-üstə düşməlidir. Serverdə transformer: superjson qoşulubsa, onu httpBatchLink-ə də əlavə etmək lazımdır.

Qalır tətbiqi app/layout.tsx-də əhatə etmək: