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•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-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•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•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•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 entriesfirm-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