I did everything according to the documentation, but there is no server rendering
I have created a page
app/layout.tsx
export default async function RootLayout({children}: {children: React.ReactNode}) {
const queryClient = getQueryClient()
const dehydratedState = dehydrate(queryClient)
return (
<html>
<body>
<Providers>
<HydrationBoundary state={dehydratedState}>
{children}
</HydrationBoundary>
</Providers>
</body>
</html>
)
}
Providers
'use client'
import React, { useState } from 'react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
function Providers({ children }: React.PropsWithChildren) {
const [client] = useState(
new QueryClient({ defaultOptions: { queries: { staleTime: 60 * 1000 } } })
)
return (
<QueryClientProvider client={client}>
{children}
</QueryClientProvider>
)
}
export default Providers
Page
export default async function AdminUsersList() {
const queryClient = getQueryClient()
await queryClient.prefetchInfiniteQuery({
queryKey: ['users'],
queryFn: () => fetchUsers(0),
initialPageParam: 0
})
return (
<UserList />
)
}
userlist
export default function UserList() {
const {
data: users,
fetchNextPage,
hasNextPage,
isLoading,
isError,
} = useUsers()
if (isLoading && !users) return <>loading...</>;
return (
<div>
{!isLoading && users && (
<InfiniteScroll
pageStart={0}
hasMore={!isError && hasNextPage}
loader={<Preloader key='loader' />}
loadMore={() => fetchNextPage({ cancelRefetch: false })}
>
<div>
{users.pages.map((group, i) => (
<React.Fragment key={i}>
{group.users.map((user) => (
{user.username}
))}
</React.Fragment>
))}
</div>
</InfiniteScroll>
)}
</div>
)
}
getQueryClient
import { QueryClient } from "@tanstack/react-query"
const getQueryClient = () => new QueryClient()
export default getQueryClient
fetchUsers
import { Error } from '@/types/error'
import { User } from '@/types/entities/user'
import { useInfiniteQuery } from '@tanstack/react-query'
interface Response {
users: User[],
nextCursor: number
}
export async function fetchUsers(pageParam: unknown) {
try {
const res = await fetch(`http://localhost:3001/api/admin/users?skip=${!pageParam ? 0 : pageParam}`, { cache: 'no-store' });
return await res.json()
} catch (err: any) {
throw err.response.data
}
}
export default function useUsers() {
return useInfiniteQuery<Response, Error>({
queryKey: ['users'],
queryFn: ({ pageParam }) => fetchUsers(pageParam),
initialPageParam: 0,
getNextPageParam: (lastPage) => lastPage.nextCursor,
})
}
2
Answers
The problem was that. What should be done in each page like this
I just can't figure out why it doesn't pick it up from layout.
Your code looks mostly correct. But I have a few suggestions,
Wrap you components that rely on React Query data with Suspense and HydrationBoundary. Here is a sample code:
Thanks.