T
TanStack•12mo ago
firm-tan

state management

Hi, I have a question about getQueryState Here is my query, its on query.tsx const itemsQuery = useQuery({ queryKey: ["getAllEvents"], queryFn: async () => { const InitEvents = await getAllEvents(); InitEvents.forEach((event) => { // {name: 'my event', id: 1, date: Friday ....} queryClient.setQueryData(["InitEvents", "detail", event.id], event); }); return InitEvents; }, }); in a component page, lets call it eventDetails.tsx I have the following const queryClient = useQueryClient(); const state = queryClient.getQueryState(["getAllEvents"]); console.log(state && state.data[[${eventId}]]); now, it works well when I come from the page that loads that query, but on the component page, if I refresh or navigate directly, the data is undefined. is there a better way to make "global state" available (this state does change and update, so its semi-persistant if thats a thing) I'm trying to avoid making an API call every time I only started using react-query today, so bare with me 🙂
6 Replies
multiple-amethyst
multiple-amethyst•12mo ago
Move the useQuery to its own file and use it both in the page and the component It wont make the call every time. It will only refetch if the data is marked as stale (eg by invalidating it or by setting a staleTime) or if youre using refetchOnMount/similar
firm-tan
firm-tanOP•12mo ago
thanks! that's what I ended up doing after some further trial and error, I will update with the code for anyone in the future
conscious-sapphire
conscious-sapphire•12mo ago
I'd also add a couple notes... You wouldn't want to setQueryData yourself in your own queryFn. Just return the data and let RQ cache it. When saying a refresh data is undefined, do you mean entire page refresh? Because RQ cache is in memory but there are persistent plugins if you desire, like localStorage. Lastly, using getQueryData won't create a subscriber so if data changes your component won't "hear" it. useQuery is always preferred (as Tim mentioned).
conscious-sapphire
conscious-sapphire•12mo ago
If you're new to RQ might I suggest Dominik's blogs. They go into great detail in a variety of topics https://tkdodo.eu/blog/all
Blog
A technical blog about frontend-development, TypeScript and React
flat-fuchsia
flat-fuchsia•12mo ago
queryClient.getQueryState is not reactive. It just reads what is in the cache, and you'll get undefined if there's nothing in it. What you want is just another useQuery that subscribes to ["InitEvents", "detail", event.id] , which will fetch the single event if it does not exist if you don't have a dedicated details endpoint, you can use select to pick something from the list query. But it will always fetch the whole list, even if you only need a single entry. And then you wouldn't need the seeding pattern to create separate detail entries
firm-tan
firm-tanOP•12mo ago
I think overall, I wonder if I can remove other state management pkgs i.e save the initial query, use it everywhere (instead of passing as props), would be a bonus if the initial data can update if new information is pushed. right now, lets say I have 100 blog posts, in theory I am making an API call every time I need to access this data get blog post by ID is possible but I'm exploring my options

Did you find this page helpful?