Update query config when new config is provided #962
-
Consider: queryCache.setQueryData("posts", [
// this could be set to something useful,
// but it's irrelevant for this example
]);
function usePosts() {
return useQuery("posts", async () => {
// 🚨 This function will *never* be called 🚨
const { data } = await axios.get(
"https://jsonplaceholder.typicode.com/posts"
);
return data;
});
} Here's the broken app: https://4cq8j.csb.app/ Here's the code: https://codesandbox.io/s/cranky-goodall-4cq8j?file=/src/index.js (I noticed that Codesandbox's fast-refresh "fixes" the issue though, so don't trust that, open the app by itself). The problem is simple: The first thing to create a query object will keep that config forever. So because I think the solution is to merge the query config that's in the query cache for a given query. So at some point when |
Beta Was this translation helpful? Give feedback.
Replies: 10 comments 10 replies
-
What's interesting is that I observe that sometimes it appears that the queryFn will get called. Still investigating the situation. But from what I'm noticing is that the queryCache does not update the queryFn for the query within the cache. So the code that actually does call the queryFn is not getting the function from the cache, but from the hook call. This may explain why codesandbox's fast-refresh makes it work eventually. |
Beta Was this translation helpful? Give feedback.
-
If it helps, here's the PR where I update react-query: https://github.com/kentcdodds/bookshelf/pull/66/files#diff-b9cfc7f2cdf78a7f4b91a753d10865a2L30-R31 One test fails due to this bug (I guess I should've made an issue instead of a discussion). |
Beta Was this translation helpful? Give feedback.
-
If it helps, this test starts breaking on [email protected] (it works with [email protected]). Here's the diff: v2.13.0...v2.13.1 |
Beta Was this translation helpful? Give feedback.
-
This is caused by the recent change on how queries are configured. Let me try to explain: The query is a singleton, but there can be multiple hooks attached to the query, each with different configurations and query functions. Previously the query configuration was set during render, which means the query configuration would change multiple times during a render and the eventual configuration was dependent on the rendering order. This could cause inconsistent behaviour. To resolve this, the query configuration is now set, only when a hook or prefetch executes the query. In this case the hook mounts, but because there is fresh data in the cache, it will not execute the query. When the window is re-focussed, it will try to refetch the last executed configuration, which in this case, does not have a query function defined. I'm not 100% sure on what the right approach is here, but I also wouldn't expect a |
Beta Was this translation helpful? Give feedback.
-
Sounds like we may need to have some parts of the query always updating on render, eg. certain configuration options that only apply to the query instance and not the individual observable/hook instance. One of those is the queryFn which (at least as it is defined today) shouldn't be changing underlying behavior across your application (Note that it's still okay for its identity to change from render to render eg. |
Beta Was this translation helpful? Give feedback.
-
Thinking about this more, I'm not sure what's wrong with just updating the core query config with the latest rendered observer config. Anywhere we are relying on the actual config for the query, we'll be pulling it from the query instance itself and it shouldn't be changing across your app, and likewise anywhere we want observer-specific config, we should be pulling it from the observer. Thoughts? |
Beta Was this translation helpful? Give feedback.
-
Let's try to break down in which situations a query is executed and which configuration is used:
Currently on window focus, the query will check if there are any observers which indicate they are enabled, stale and have Because of the issue mentioned here, and also because the hook which triggered the last fetch might not be mounted anymore, maybe it would be better if it would use the configuration from the first observer which is enabled, stale and has When updating on render it could happen that the query would use a configuration from a hook which is disabled, not stale, or has |
Beta Was this translation helpful? Give feedback.
-
I wasn't aware of this discussion and created an issue regarding this behavior: #963 Note: even when providing a query-config in prefetch-query then only |
Beta Was this translation helpful? Give feedback.
-
@kentcdodds the issue should be fixed now in |
Beta Was this translation helpful? Give feedback.
-
@tannerlinsley @boschni I'm having this same issue, but coming through refetchQueries instead. Basically, the sequence looks like this:
I noticed that @tannerlinsley suggested above
It seems like this would solve this class of problems once and for all -- is this a possibility? Update: |
Beta Was this translation helpful? Give feedback.
@kentcdodds the issue should be fixed now in
2.15.1