Is there a supported and documented way to get access the query caches outside of the context of React? This is something that a competitor redux-query offers.
Users with existing architecture based on Redux, Reselect, Redux Saga, etc. might have a hard time migrating existing code without major refactoring unless this is possible. You already expose a way to write to the cache outside of React, so it seems natural to add read access as well. I understand it may not be so clean, but it might be important to help ensure apps have a path to move to the newer paradigm.
Here's a snippet of code I was able to use to access the React Query caches from outside of a React context - not relying on the hook to access - but I don't want to assume this is a supported approach for now.
import { queries } from "react-query";
const getQuery = queryKey =>
queries.find(
query => query.config.queryKeySerializerFn(queryKey)[0] === query.queryHash
);
const getQueryCache = queryKey =>
getQuery(queryKey) && getQuery(queryKey).state.data;
Example usage:
getQueryCache(["myQuery", { myArg: 1 }]);
We could consider extending support to accept a custom function to match against arguments in different ways - in case the user wishes to match any arguments, or only a subset of arguments, or with multiple values for given argument(s), etc.
Also maybe, if prefetchQuery and/or refetchQuery don't support this already, we could also expose the ability to fetch (or re-fetch) a query from outside of React. Here's an example function:
import { queries } from "react-query";
const getQuery = queryKey =>
queries.find(
query => query.config.queryKeySerializerFn(queryKey)[0] === query.queryHash
);
const getQueryCache = queryKey =>
getQuery(queryKey) && getQuery(queryKey).state.data;
const fetchQuery = queryKey => getQuery(queryKey) && getQuery(queryKey).fetch();
Example usage:
fetchQuery(["myQuery", { myArg: 1 }]);
Here we may want to also include a call to makeQuery inside fetchQuery in case the query hasn't yet been fetched or prefetched so that this still works in those cases.
As far as I can tell there is nothing wrong with accessing the query like you have, other than it being undocumented. It's highly unlikely to change in this major version, but not impossible.
As fo the fetching, that also theoretically should work. The existing refetchQuery logic doesn't rely on react too much afaik.
@tannerlinsley Thanks, good to know! Might it still be worth creating a supported functions exported for the read cache and/or fetch use cases?
For fetching, I think we'd want a combination of prefetchQuery which can make a query if it doesn't yet exist, but in other ways more like refetchQuery in that it perhaps doesn't unsubscribe and doesn't set config.prefetch since that seems to skip the mount fetch for hooks whereas we might like to rely only on the cache to decide whether a refetch on mount would be appropriate even after perhaps manually fetching the query previously outside of React before the component has mounted.
Thoughts?
@tannerlinsley It'd be awesome to have this feature, I too need this functionality, currently I am using it the way that is described above, not very optimal though, can we store state using hash keys instead of an array?
I have existing code in Redux and sometimes I have a hard time getting the state from react-query, it requires passing props, it can be solved using Context on top of React query, but most of the times I need data for read-only purpose and not for render/re-render, so using Context doesn't make any sense.
It's like we need redux but with the declarative power of react-query 馃槃
I am willing to try to implement in some PRs if there is interest from @tannerlinsley.
@AndersDJohnson This would be great as it can also then lead to an efficient guide of how to migrate from other libraries to this one.
I'll consider this for the next major release, but for now, you can use the workaround described above.
Maybe I am missing smth, but isn't this easily and elegantly achievable by explicitly setting QueryCache via ReactQueryCacheProvider? If you create a single instance of QueryCache that you pass to ReactQueryCacheProvider, you can also export that instance for the rest of the app to import it and use it, even outside of React, right?
Yep. A lot has changed since this issue. You can now easily just access/export your new QueryCache() instance (in v3, it will be your QueryClient instance).
Most helpful comment
Yep. A lot has changed since this issue. You can now easily just access/export your
new QueryCache()instance (in v3, it will be your QueryClient instance).