unwilling-turquoise
unwilling-turquoise2mo ago

TQ cache isn't working in existing project

Hi, I'm new here and enjoying Refine so far, but there's an issue with Tanstack Query not caching. This is in an existing project that also uses Apollo, not sure if that's a conflict.
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: 1,
refetchOnWindowFocus: false,
staleTime: 5 * 60 * 1000, // 5 minutes
gcTime: 10 * 60 * 1000, // 10 minutes
refetchOnMount: false,
refetchOnReconnect: false
}
}
})

<QueryClientProvider client={queryClient}>
<DevtoolsProvider>
<Refine
dataProvider={{
default: buyingProductDataProvider,
buyingProduct: buyingProductDataProvider
}}
options={{
// ...tried this too, but removed it...
reactQuery: {
clientConfig: {
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000, // 5 minutes
cacheTime: 10 * 60 * 1000, // 10 minutes
refetchOnWindowFocus: false
}
}

// in the useList hook, which works, I'm passing:
queryOptions: {
queryKey: ['buyingProduct', 'list']
}
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: 1,
refetchOnWindowFocus: false,
staleTime: 5 * 60 * 1000, // 5 minutes
gcTime: 10 * 60 * 1000, // 10 minutes
refetchOnMount: false,
refetchOnReconnect: false
}
}
})

<QueryClientProvider client={queryClient}>
<DevtoolsProvider>
<Refine
dataProvider={{
default: buyingProductDataProvider,
buyingProduct: buyingProductDataProvider
}}
options={{
// ...tried this too, but removed it...
reactQuery: {
clientConfig: {
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000, // 5 minutes
cacheTime: 10 * 60 * 1000, // 10 minutes
refetchOnWindowFocus: false
}
}

// in the useList hook, which works, I'm passing:
queryOptions: {
queryKey: ['buyingProduct', 'list']
}
I've implemented a data provider with getList and have made a useList call, but logging queryClient.getQueryCache().getAll().length returns 0 repeatedly. I tried and Tanstack's useQuery does populate the cache correctly, but I'd like to get Refine working. My goal is to see if I can have getList auto-trigger after update, which would reduce a tone of manual refetch code. Am I missing something in my setup? Thanks in advance, - MG
6 Replies
kapa.ai
kapa.ai2mo ago
Hi @centric_mg. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information in the knowledge sources, here are some key points and troubleshooting steps for your TanStack Query (TQ) cache issue with Refine: 1. Refine and QueryClientProvider
Refine already wraps your app with a QueryClientProvider internally. If you wrap your app with another QueryClientProvider (as in your code), it can cause issues, including cache not being shared or recognized as expected. The recommended approach is to let Refine manage the QueryClient, and if you need to customize it, pass your config via the reactQuery.clientConfig option in the <Refine /> component, not by wrapping with your own provider. Wrapping with your own provider may result in multiple QueryClient instances, which can cause cache issues and unexpected behavior Refine <Refine> options: reactQuery Github Issue #5499. 2. Custom QueryClient Configuration
If you want to customize the QueryClient (e.g., set staleTime, cacheTime, etc.), do so via the options.reactQuery.clientConfig prop on <Refine />:
<Refine
options={{
reactQuery: {
clientConfig: {
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000,
cacheTime: 10 * 60 * 1000,
refetchOnWindowFocus: false,
},
},
},
},
}}
// ...other props
/>

<Refine
options={{
reactQuery: {
clientConfig: {
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000,
cacheTime: 10 * 60 * 1000,
refetchOnWindowFocus: false,
},
},
},
},
}}
// ...other props
/>

This ensures Refine and TanStack Query are using the same client and cache Refine <Refine> options: reactQuery. 3. Query Keys and useList
Refine uses structured query keys for caching. If you override the queryKey in queryOptions (as in your useList usage), make sure it matches the key structure Refine expects, or you may break cache linkage. Normally, you should let Refine generate the query key unless you have a specific advanced use case Key Structure. 4. Cache Not Populating
If queryClient.getQueryCache().getAll().length returns 0, it suggests that either: - The QueryClient you are inspecting is not the one Refine is using (likely due to multiple providers). - The queries are not being registered due to a mismatch in query keys or improper setup. 5. Apollo Conflict
There is no explicit mention in the knowledge sources of Apollo causing a conflict with Refine or TanStack Query, but ensure that you are not mixing providers or hooks in a way that could cause context issues. 6. Automatic Refetch After Mutation
Refine automatically invalidates and refetches related queries after mutations, provided the cache and key structure are set up correctly State Management. Recommended Fix: - Remove your custom <QueryClientProvider> wrapper and let Refine manage it. - Pass your query client config via <Refine options={{ reactQuery: { clientConfig: ... } }} />. - Avoid overriding queryKey in useList unless necessary; let Refine handle it for best compatibility. - Make sure you are using compatible versions of Refine and TanStack Query (Refine v4 is compatible with TanStack Query v4; v5 support is in progress) Github Issue #5499. If you follow these steps and still see no cache, double-check that you are not using multiple versions of TanStack Query or Refine, and that your data provider is returning data as expected. If you need to inspect the cache, use the same QueryClient instance that Refine is using, or use the React Query Devtools as described in the docs. I'm sorry, but the knowledge sources do not provide information about Apollo-specific conflicts, so if the above steps do not resolve your issue, consider isolating Apollo from your Refine setup to test for interference. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@1390122508468092998> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
unwilling-turquoise
unwilling-turquoiseOP2mo ago
@kapa.ai I tried removing the extra provider wrapper, and using the vanilla <Refine> setup you suggested, but not sure if there's a way to access the TQ client to verify that it's caching? Note that the docs here do show that you can provide your own client: https://refine.dev/docs/core/refine-component/#clientconfig I tried doing this (without the extra wrapper) but I get typescript errors, TS2322: Type 'QueryClient' is not assignable to type 'QueryClientConfig | QueryClient'. Type 'QueryClient' is missing the following properties from type 'QueryClient': queryCache, mutationCache, logger, defaultOptions, and 4 more. 37 | reactQuery: {
38 | clientConfig: queryClient
| ^^^^^^^^^^^^ 39 | } 40 | }} 41 | > I tried suppressing those using as any, and also removing the DevTools provider from the setup so it's very clean, but still see an empty cache.
<Refine> | Refine
`` component is the entry point of a Refine app. It is where the highest level of configuration of the app occurs.
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're correct that the Refine documentation shows you can provide your own QueryClient instance via the clientConfig prop on <Refine /> Refine <Refine> options: reactQuery. The example from the docs is:
import { QueryClient } from "@tanstack/react-query";

const myQueryClient = new QueryClient();

const App = () => (
<Refine
options={{
reactQuery: {
clientConfig: myQueryClient,
},
}}
// ...other props
/>
);
import { QueryClient } from "@tanstack/react-query";

const myQueryClient = new QueryClient();

const App = () => (
<Refine
options={{
reactQuery: {
clientConfig: myQueryClient,
},
}}
// ...other props
/>
);
If you're getting a TypeScript error like:
Type 'QueryClient' is not assignable to type 'QueryClientConfig | QueryClient'.
Type 'QueryClient' is not assignable to type 'QueryClientConfig | QueryClient'.
this suggests a possible version mismatch between your installed @tanstack/react-query and the types expected by your version of Refine. The knowledge sources indicate that Refine v4 is compatible with TanStack Query v4, and there have been issues when using v5 Github Issue #5499. If you are using TanStack Query v5, you may encounter type or runtime issues. How to access the QueryClient to verify caching: - You can use the useQueryClient hook from @tanstack/react-query inside your components to access the QueryClient instance that Refine is using. For example:
import { useQueryClient } from "@tanstack/react-query";

const MyComponent = () => {
const queryClient = useQueryClient();
// You can now inspect queryClient.getQueryCache().getAll()
// or use React Query Devtools for a UI view
}

import { useQueryClient } from "@tanstack/react-query";

const MyComponent = () => {
const queryClient = useQueryClient();
// You can now inspect queryClient.getQueryCache().getAll()
// or use React Query Devtools for a UI view
}

- The knowledge sources do not provide a method to access the QueryClient outside of React components, but inside components, this is the recommended approach useQueryClient reference. Summary of steps: 1. Ensure you are using compatible versions: Refine v4 with TanStack Query v4. 2. Pass your QueryClient instance via clientConfig as shown above. 3. Use useQueryClient inside a component to inspect the cache. If you still see an empty cache, double-check your versions and ensure your data provider and hooks are set up correctly. If the problem persists, the knowledge sources do not provide further troubleshooting steps for this specific scenario. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@1390122508468092998> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
unwilling-turquoise
unwilling-turquoiseOP2mo ago
That was it – Version 4 works. Sad it didn't just say so in the docs and I didn't find the Github issue! Thanks

Did you find this page helpful?