T
TanStack3y ago
absent-sapphire

Query refetching using hydration for Next 13 experimental app

I'm trying to follow the docs on prefetching data using the new experimental next 13 app directory. However I find it hard to understand how prefetching actually works Server component:
export default async function HydratedPosts() {
const queryClient = getQueryClient()
await queryClient.prefetchQuery(['posts'], getPosts)
const dehydratedState = dehydrate(queryClient)

return (
<Hydrate state={dehydratedState}>
<Posts />
</Hydrate>
)
}
export default async function HydratedPosts() {
const queryClient = getQueryClient()
await queryClient.prefetchQuery(['posts'], getPosts)
const dehydratedState = dehydrate(queryClient)

return (
<Hydrate state={dehydratedState}>
<Posts />
</Hydrate>
)
}
Cache is initialized by prefetchQuery(). Client component is then dehydrated and rehydrated based on the cache. Client component:
export default function Posts() {
const { data } = useQuery({ queryKey: ['posts'], queryFn: getPosts })
//...
}
export default function Posts() {
const { data } = useQuery({ queryKey: ['posts'], queryFn: getPosts })
//...
}
We retrieve the data that was previously prefetched/cached in server. Question: 1. When does this dehydration/rehydration get triggered? Is it whenever the data(in this case 'posts') get invalidated? 2. In docs it says Query refetching is based on when the query was prefetched on the server. Does this mean, query refetching (client component) happens whenever prefetching (server component) happens? Then, how would we trigger server prefetching that would trigger refetching? In my mind, it's cache invalidated -> prefetch at server -> refetch at client. Is this correct on how I understand what doc meant by query refetching? Because it didn't quite feel right to say that server is prefetching multiple times. 3. What is this dehydration/rehydration actually about? As far as I understand, it's about detaching/attaching event listeners on the client's DOM that has been pre-rendered and served to browser from the server. Also, in terms of react query, hydrating query is about being able to use React Query's full capability on the query. So, initially before hydration, prefetched data do not have much capacity to do things like refetching the query, but after hydration happens in client, we can now refetch the query?
1 Reply
absent-sapphire
absent-sapphireOP3y ago
I wanted to include the actual problem that happened with my project but due to discord word count limitation, I'm asking here instead... So in my project, I'm using supabase to prefetch the data in server component:
export async function getCategories() {
const supabase = createClient();
const { data } = await supabase
.from('category')
.select();

return data;
}
export async function getCategories() {
const supabase = createClient();
const { data } = await supabase
.from('category')
.select();

return data;
}
I can only call this getCategories function in server component, but not in client component (it results in error about being unable to use cookies, headers used in supabase client in client component) However, I think I need to provide the same fetching function to both server and client component like this: Server
await queryClient.prefetchQuery(['categories'], getCategories)
await queryClient.prefetchQuery(['categories'], getCategories)
Client
const { data } = useQuery({ queryKey: ['categories'], queryFn: getCategories })
const { data } = useQuery({ queryKey: ['categories'], queryFn: getCategories })
Since I cannot share same fetching function for server and client, should I create client version of fetching data that returns same data as fetching function defined in server component? .

Did you find this page helpful?