After displaying a list (data coming from a query), a component use a mutation to post some new data that would go to this list. After mutation succeed, I invalidate the query cache (multiple techniques were tried, with different and most of the time expected results, see below) concerning the queries, then push back the list on to history.
The techniques I used to invalidate the cache are the following:
await queryCache.refetchQueries(["items"]);
{force: true}await queryCache.refetchQueries(["items"], {force: true});
await queryCache.removeQueries(["items"]);
queryCache.getQueries(["items"]).forEach((query) => {
query.state.isStale = true;
});
With default configuration, every method works (with slightly different but expected behaviors).
With react-query configured to use a non-default staleTime though, only 2, 3 and 4 works, as refetchQueries (and more specifically the fetch method on the query will ignore non-stale queries if not forced.
Although after reading the code I understand this is the expected behavior, I think there are a few defects :
refetchQueries and suggest to do so. It makes it hard to debug as there are no pointers to what can make the refetching not happen.react-query does the rest (with old data shown while refetching). Refetching all queries related may be a bit too much, most of them may be never used again. Would it be possible to add an api method to queryCache to setQueriesAsStale (or whatever english describes this best) ? Then it could be shown as an alternative to refetch in documentation once mutation is done.I can work on a patch (code, tests and doc) if this makes sense.
I think staleTime works as I expect and per the docs. But I do agree it鈥檇 be nice to have an api for marking a query/queries as stale.
It would probably be quite easy to abstract the stale-setting logic into a util and add an invalidateQueries method to the cache.
I鈥檇 also be happy to pick this up if wanted as it鈥檚 something I was initially unsure about triggering (luckily all of my usecases so far have been solved by the force flag)
I think this would be a good addition or fix to the library. I would expect this new function to be something like invalidateQueries. It would allow invalidating multiple queries. If those queries are currently in use on the page (they have open instances to them), they should get refetched, if they do not, then they should be marked as stale. Thoughts?
The next major version will include 2 ways to do this:
refetchQueries(queryKey, { lazy: true }. This will automatically detect whether a query is currently being rendered on screen or not and if it is, it will be refetched, if it is not, it will be invalidated (instead of previously being refetched as well).invalidateQueries method that will loop over all matched queries and set their internal state to stale. This will not trigger a refetch, so any queries that are currently being used on the page would remain in their stale state.This is great news!
Will the refetchQueries(queryKey, { lazy: true } only refetch when the query is not fresh (like regular refetch), or will it invalidate (set stale) first to ensure refetching is done ?
I guess both are fine but as it can create some headaches, it should be pretty clear in the docs what happens in each refetch situation.
Thanks!
I'm still working on it. But now I'm thinking it will be more like this: refetchQueries is now gone and replaced by invalidateQueries. invalidateQueries(queryKey) will at the very least invalidate every query it matches no matter what and (by default) will also trigger a refetch for queries that are currently in use via useQuery (and friends). You can turn this off via invalidateQueries({ refetchActive: false })
Fixed in the pending Next PR. Huzzah!
I'm still working on it. But now I'm thinking it will be more like this:
refetchQueriesis now gone and replaced byinvalidateQueries.invalidateQueries(queryKey)will at the very least invalidate every query it matches no matter what and (by default) will _also_ trigger a refetch for queries that are currently in use viauseQuery(and friends). You can turn this off viainvalidateQueries({ refetchActive: false })
You might wanna mentioned this in the "Async data made simple with React Query" video on YT. 馃檪
Most helpful comment
I think this would be a good addition or fix to the library. I would expect this new function to be something like
invalidateQueries. It would allow invalidating multiple queries. If those queries are currently in use on the page (they have open instances to them), they should get refetched, if they do not, then they should be marked as stale. Thoughts?