util/ReactQueryProvider
'use client'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import { PropsWithChildren, useState } from 'react'
export default function ReactQueryProvider({ children }: PropsWithChildren) {
const [queryClient] = useState(() => new QueryClient())
return (
<QueryClientProvider client={queryClient}>
{children}
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
)
}
util/getQueryClient
import { QueryClient } from '@tanstack/query-core'
import { cache } from 'react'
const getQueryClient = cache(() => new QueryClient())
export default getQueryClient
util/HydrateOnClient
'use client'
import { Hydrate as HydrateOnClient } from '@tanstack/react-query'
export default HydrateOnClient
app/layout
import './globals.css'
import { Inter } from 'next/font/google'
import ReactQueryProvider from '../util/ReactQueryProvider'
const inter = Inter({ subsets: ['latin'] })
export const metadata = {
title: 'Plant gallery',
description: 'Show your plant',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={inter.className}>
<ReactQueryProvider>{children}</ReactQueryProvider>
</body>
</html>
)
}
app/list/fetch
import { ObjectId } from 'mongodb'
type ListData = {
_id: ObjectId
title: string
content: string
}
export const getList = async () => {
const res = await fetch(
`${process.env.NEXT_PUBLIC_BASE_FETCH_URL}/api/post/list`,
)
const data = await res.json()
return data as ListData[]
}
app/list/HydratedList
import { dehydrate } from '@tanstack/query-core'
import getQueryClient from '@/util/getQueryClient'
import HydrateOnClient from '@/util/hydrateOnClient'
import { getList } from './fetch'
import ListItem from './ListItem'
export default async function HydratedList() {
const queryClient = getQueryClient()
await queryClient.prefetchQuery(['list'], getList)
const dehydratedState = dehydrate(queryClient)
return (
<HydrateOnClient state={dehydratedState}>
<ListItem />
</HydrateOnClient>
)
}
app/list/ListItem
'use client'
import { useQuery } from '@tanstack/react-query'
import Link from 'next/link'
import { getList } from './fetch'
export default function ListItem() {
const { data } = useQuery(['list'], getList, { staleTime: 10 * 1000 })
return (
<>
{data &&
data.map((el) => (
<div key={el.title}>
<Link href={`/detail/${el._id}`}>{el.title}</Link>
<Link href={`/edit/${el._id}`}>✏️</Link>
<button
type="button"
onClick={(e) => {
fetch('/api/post/delete', {
method: 'POST',
body: `${el._id}`,
})
}}
>
🗑️
</button>
</div>
))}
</>
)
}
React Example: Nextjs
How to Setup React Query in Next.js 13 App Directory
Next.js 13 버전에서 ReactQuery 사용시 서버 컴포넌트에서 클라이언트 컴포넌트로 pre-fetch 데이터 전달하는 방법
'SomeComponent' cannot be used as a JSX component.