// /stores/queryProvider.tsx
"use client";
import { isServer, QueryClient, QueryClientProvider } from "@tanstack/react-query";
function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000,
},
},
});
}
let browserQueryClient: QueryClient | undefined = undefined;
function getQueryClient() {
if (isServer) {
return makeQueryClient();
} else {
if (!browserQueryClient) browserQueryClient = makeQueryClient();
return browserQueryClient;
}
}
export default function Providers({ children }: { children: React.ReactNode }) {
const queryClient = getQueryClient();
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
}
먼저 세팅을 해주자. 위 코드는 넥스트에서 제공해주는 세팅 코드이다.
그렇게 만들어진 Provider을 root layout에서 감싸준다.
import type { Metadata } from "next";
import "./globals.css";
import Providers from "./stores/queryProvider";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import Link from "next/link";
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>
<header>
//...
</header>
<Providers>
<ReactQueryDevtools />
{children}
</Providers>
</body>
</html>
);
}
이렇게 root layout에서 감싸주면 된다.
"use client";
import { getTodosSSR } from "@/server-action";
import { useQuery } from "@tanstack/react-query";
import React from "react";
const NormalFetchTodosPage = () => {
const { data: todos } = useQuery({
queryKey: ["normalFetchedTodos"],
queryFn: () => {
console.log("isnt preFetched");
return getTodosSSR();
},
staleTime: 1000,
});
return (
<div>
<h1>Normal Todos Page</h1>
<ul>
{todos?.map((todo) => {
return <li key={todo.id}>{todo.title}</li>;
})}
</ul>
</div>
);
};
export default NormalFetchTodosPage;
그리고 어떤 컴포넌트에서 useQuery를 잘 사용할 수 있다.
prefetch를 사용하려면
import PrefetchedTodos from "@/components/PrefetchedTodos";
import { getTodos } from "@/server-action";
import { dehydrate, HydrationBoundary, QueryClient } from "@tanstack/react-query";
import React from "react";
const PrefetchPage = async () => {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 10,
},
},
});
await queryClient.prefetchQuery({
queryKey: ["prefetchedTodos"],
queryFn: () => {
console.log("prefetched!");
return getTodos();
},
});
return (
<HydrationBoundary state={dehydrate(queryClient)}>
<PrefetchedTodos />
</HydrationBoundary>
);
};
export default PrefetchPage;
"use client";
import { Todo } from "@/server-action";
import { useQuery } from "@tanstack/react-query";
import React from "react";
const PrefetchedTodos = () => {
const {
data: todos,
isLoading,
isError,
} = useQuery({
queryKey: ["prefetchedTodos"],
queryFn: async () => {
console.log("isPrefetched?");
const res = await fetch("http://localhost:4000/todos");
const data: Todo[] = await res.json();
return data;
},
staleTime: 1000 * 60 * 10,
});
if (isLoading) return <>Loading...</>;
if (isError) return <>error</>;
return (
<div>
<h1>Prefetched Todos Page</h1>
<ul>
{todos?.map((todo) => {
return <li key={todo.id}>{todo.title}</li>;
})}
</ul>
</div>
);
};
export default PrefetchedTodos;
이렇게 미리 fetch해놔서 사용자경험을 증가시킬 수 있다.
'2차 공부 > TIL' 카테고리의 다른 글
24.10.01 트러블 슈팅 (1) | 2024.10.02 |
---|---|
24.09.30 트러블 슈팅 (0) | 2024.10.02 |
24.09.25 nextjs의 4가지 주요 렌더링 기법 (0) | 2024.09.25 |
24.09.23 팀프로젝트 마무리 (2) | 2024.09.23 |
24.09.20 팀프로젝트 진행상황 (1) | 2024.09.20 |