T
TanStack15mo ago
harsh-harlequin

How Does removeQueries work with placeholderData:KeepPreviousData??

Hey everyone. I'm trying to build an application where user can have business accounts. Business Account are what drives the 90% of my application. Change in Business Account should remove all the cached queries and fetch settings data to provide globally. The Issue I am facing is with queryClient.removeQueries and placeholderData:keepPreviousData. Every time I switch business. All the cached data get's removed but the page that I am currently In uses the previousQuery data until the data for the new business resolves resulting into isLoading being false and isPlaceholderData being true. What I want is to show Skeleton in every places when ever the business get's changed. Here is a minimal reproduction https://codesandbox.io/p/sandbox/demo-4wvwr4?file=%2Fsrc%2FApp.js
12 Replies
harsh-harlequin
harsh-harlequinOP15mo ago
@TkDodo 🔮 can you please help me with this?
foreign-sapphire
foreign-sapphire15mo ago
you'd want to use queryClient.resetQueries
harsh-harlequin
harsh-harlequinOP15mo ago
resetQueries works but It doesn’t remove the cache data for previously selected business. Do you want me to use both resetQueries and removeQueries
foreign-sapphire
foreign-sapphire15mo ago
resetQueries resets it to its initial state. unless you use initialData, you should see the query go to status: 'pending' with undefined data
harsh-harlequin
harsh-harlequinOP15mo ago
I got to know about it through docs. But I want cached data related to previous business to be cleared as well. queryClient.resetQueries doesn't do that. So What should I be using for that??
harsh-harlequin
harsh-harlequinOP15mo ago
No description
foreign-sapphire
foreign-sapphire15mo ago
queryClient.resetQueries({ queryKey: ['party'] })
harsh-harlequin
harsh-harlequinOP15mo ago
Sorry for not being able to clarify the issue more clearly. Only the currently selected business query should be in cache. All of the cache related to previous business should be cleared, When switching Business. In the picture you could see that the cache for the previous business isn't being removed and I am using queryClient.resetQueries Here is a minimal reproduction of the issue: https://codesandbox.io/p/sandbox/demo-4wvwr4?file=%2Fsrc%2FApp.js
No description
foreign-sapphire
foreign-sapphire15mo ago
so why doesn't removeQueries work in this example? when the id = 1, and I switch the select to id = 2: - removeQueries will remove all elements. - then you switch business - then data for id = 2 will be visible while you switch business, id = 1 is still displayed on the screen because the component already rendered it. you'd need to unmount the component if that's what you want
harsh-harlequin
harsh-harlequinOP15mo ago
Since I am removing all the cached queries. Doesn't it make sense to reset the query state as well?. Right now I am using removeQueries and every query is configured with placeholderData:keepPreviousData. When Switching Business, The cache does get cleared, But I see the previousQuery data being shown until the data for new business arrives. Rather than showing the previously selected business data. I want to show a loading state to a user. Does this makes sense? And for me to show loading state the query state must be reset Right now I am ummounting the component using businessIdx. But It doesn't work in the case where I need to preserve client state between switching business
foreign-sapphire
foreign-sapphire15mo ago
I wanted to also suggest that setting a key=id will make sure your component re-mounts. But yeah, that will nuke client state too. Interesting that it's a use-case to keep client state between switching something global like a business that should nuke all queries 🤷‍♂️ here is what the functions do: - removeQueries: removes data from the cache for matching queries, but does not re-render components. - resetQueries: sets data back to initialState, and re-renders components. If you do that, you will likely see a refetch + pending state for the old id, because the component is still mounted with that id when you call it. - keepPreviousData: This is a "per-component", not "per-query" setting. So setting placeholderData:keepPreviousData will keep data on screen if the componen re-renders and the query key changes. The only way to nuke is to re-mount the component (which also nukes client state). what you can do is implement a smart placeholderData:
placeholderData: (previousData) => previousData?.id === id ? previousData : undefined
placeholderData: (previousData) => previousData?.id === id ? previousData : undefined
that will make sure that previousData is only kept if the ids are still the same, and a business switch should take away previousdata
harsh-harlequin
harsh-harlequinOP15mo ago
For now, there is no use case for preserving states between switching business. I was only asking you to know If there is any other way to do that without unmounting the component 😅.
Placeholder Data seem to be a solution but the api response doesn't have businessId we can compare against. So I think key should work fine Thanks @TkDodo 🔮

Did you find this page helpful?