T
TanStack•16mo ago
exotic-emerald

Query not working correctly until changing query key to a new, clean one

Hi everyone. My query doesn't fetch data server side after I changed the query key forward and then back. The part that confuses me is that I don't use any external storage plugins, but the issue resolves if I change the key to a new, clean value. Restarting the app doesn't help. How does React Query preserve cache between app starts?
12 Replies
firm-tan
firm-tan•16mo ago
it doesn't. please show a reproduction
exotic-emerald
exotic-emeraldOP•16mo ago
My bad. Changing key not solving the issue, but I noticed that this issue happens only if use query in 2 components, and it's working fine if only in one. page.tsx:
await Promise.all([
queryClient.prefetchQuery({
queryKey: ["categories", params.locale],
queryFn: getCategories,
}),
queryClient.prefetchQuery({
queryKey: ["bundles", { top: 2, locale: params.locale }],
queryFn: () => getBundles(2),
}),
queryClient.prefetchQuery({
queryKey: ["home-page"],
queryFn: () => getHomePageContent(),
}),
]);
await Promise.all([
queryClient.prefetchQuery({
queryKey: ["categories", params.locale],
queryFn: getCategories,
}),
queryClient.prefetchQuery({
queryKey: ["bundles", { top: 2, locale: params.locale }],
queryFn: () => getBundles(2),
}),
queryClient.prefetchQuery({
queryKey: ["home-page"],
queryFn: () => getHomePageContent(),
}),
]);
component1:
const { locale } = useContext(globalContext);

const { data: categories } = useQuery<Category[]>({
queryKey: ["categories", locale],
queryFn: async () => {
console.log("1", locale);
const r = await axios.get(`/${locale}/api/categories`);
return r.data;
},
});
const { locale } = useContext(globalContext);

const { data: categories } = useQuery<Category[]>({
queryKey: ["categories", locale],
queryFn: async () => {
console.log("1", locale);
const r = await axios.get(`/${locale}/api/categories`);
return r.data;
},
});
component2:
const { locale } = useContext(globalContext);

const { data: categories } = useQuery<Category[]>({
queryKey: ["categories", locale],
queryFn: async () => {
console.log("2", locale);
const res = await axios.get(`/${locale}/api/categories`);
return res.data;
},
});
const { locale } = useContext(globalContext);

const { data: categories } = useQuery<Category[]>({
queryKey: ["categories", locale],
queryFn: async () => {
console.log("2", locale);
const res = await axios.get(`/${locale}/api/categories`);
return res.data;
},
});
If I change queryKey to ['categories2', locale], SSR is working, and when page renders I get query data immediately. Else a second passes before it loads. I'm using Next.js, if it matters.
firm-tan
firm-tan•16mo ago
Would need to see a runnable reproduction to investigate further
exotic-emerald
exotic-emeraldOP•16mo ago
Hi, I created a reproduction project, issue persists. https://github.com/korsunrodion/react-query-issue The data shows up only in couple of moments, interestingly if I remove <Footer /> from Layout.tsx, data shows up immediately GitHub
GitHub
GitHub - korsunrodion/react-query-issue
Contribute to korsunrodion/react-query-issue development by creating an account on GitHub.
firm-tan
firm-tan•16mo ago
I'm seeing hydration mismatches and also errors around:
code: 'MISSING_MESSAGE',
originalMessage: 'Could not resolve `Common` in messages for locale `en`.'
code: 'MISSING_MESSAGE',
originalMessage: 'Could not resolve `Common` in messages for locale `en`.'
maybe you could trim it down and remove the locale thingy ? also, the repro has no query devtools ..
exotic-emerald
exotic-emeraldOP•16mo ago
I updated the pr, removed next-intl. Try http://localhost:3000/en Didn't know about query devtools, I'll look into it, thanks
firm-tan
firm-tan•16mo ago
still seeing a hydration error:
<HomePage>
<HydrationBoundary>
<div>
<Home>
<div>
""
"{"id":"1","url":"/travel","title":"Categories.travel","icon":"http://localhost:3000/icons/plane.svg"}"
<HomePage>
<HydrationBoundary>
<div>
<Home>
<div>
""
"{"id":"1","url":"/travel","title":"Categories.travel","icon":"http://localhost:3000/icons/plane.svg"}"
also why is there two footers? I'm so confused ...
exotic-emerald
exotic-emeraldOP•16mo ago
Sorry, two footers are just for test, to show that issue happens depending on number of components with the query. To be honest I'm not sure what caused the hydration error, maybe it's coming from Next.js, but error and the issue stop after deleting second <Footer /> from Layout.tsx for example
firm-tan
firm-tan•16mo ago
so Layout renders Footer, but the prefetch happens somewhere else. As far as the Footer in the Layout is concerned, there is no data in the cache when this component renders it has nothing to do with amount of useQuery calls, it's all about where your prefetching is happening if you want it in the shared layout, you need to prefetch in the layout, then create a HydrationBoundary above that
exotic-emerald
exotic-emeraldOP•16mo ago
I presumed that it's enough to prefetch query server side and add hydration boundary. Any component down the tree can use this boundary, is it not? I see my mistake. Layout renders before the page, so before prefetching and hydration boundary
firm-tan
firm-tan•16mo ago
yes, exactly
exotic-emerald
exotic-emeraldOP•16mo ago
Thank you very much 🙂 Hmm, can you help with similar situation?
return (
<Layout locale={params.locale}>
<HydrationBoundary state={dehydrate(queryClient)}>
<Home />
</HydrationBoundary>
</Layout>
);
return (
<Layout locale={params.locale}>
<HydrationBoundary state={dehydrate(queryClient)}>
<Home />
</HydrationBoundary>
</Layout>
);
Layout goes before HydrationBoundary, so is Footer, but still it works and renders prefetch data. Why?

Did you find this page helpful?