-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Query keys with object property set to undefined are not considered equal to missing property during invalidation #3741
Comments
query keys are hashed deterministically, but when comparing queries, there is no hashing going on, because we have to partially compare them. For that, we use so yeah, for partial matching, there is a difference between a property being present (independent of the value, even if it's undefined), and a property being missing. |
Thanks for the quick response @TkDodo. |
I would probably create two different functions to build keys that compose each other:
|
Solution covered by a single keyPlease, take another look. I can accept your position that In my example, In comparison with another explicit invalidation, for example So two explicit queries invalidate differently because of undefined value. Key with Current behavior in the context of undefined propFor keys in cache: To have consistent behavior, react-query should do non-undefined value filtering in the comparator code before executing. Because that's exactly what seems to be happening in key hashing during record creation. My expectation in the context of undefined propIf react-query removes undefined values the same way as it does for cache record creation, it would be like this: Another solution is to allow the creation of undefined prop in the cache key record, so we can invalidate specifically only Solution with list and filteredList keysHaving two keys for one query Using two separate hooks is not a solution as I cannot swap them once the user sets the filter for my component. Other workaroundsFallback to null object
This is the closest to what I think react-query should do with Fallback to nullIf we want to consider That way I can really have something like It seems like the old topic about what is undefined and null. Undefined is JS implicit fallback for something missing. Null, on the other hand, is an explicit empty value. No matter of opinion on this, react-query is not consistent in context of ConclusionOur codebase can go with a fallback to the null or null object. But we must educate our developers that undefined value during key creation can lead to app inconsistency. |
The default key hashing uses I wouldn't really know how to change the current behaviour in a non-breaking way, do you? |
I'll reopen this because I think I misunderstood the situation. I don't think hashing is involved at all when doing partial comparisons. I'll look at this more closely again. |
Thanks for reopening. It would be my pleasure to help with this. The current behavior is very unintuitive (it took me digging through the TanStack query source code to figure out why our queries were not invalidating as expected). A few ideas come to mind at the moment:
I'm guessing that the closest we can get to the comparison behavior to work like that hash key function, the better. |
first thing would be to create a failing test case. could you do that? |
…ack#3741) The current behaviour when using function such as invalidateQueries or setQueriesData is unexpected when objects with undefined properties are involved. A key containing an object with an undefined property is hashed without the undefined property, yet the property is considered in the partialDeepEqual function. This creates some confusing scenarios as demonstrated in the discussion on TkDodo's blog <TkDodo/blog-comments#71 (comment)> and in the referenced issue This commit includes a failing test to demonstrate the expected behaviour
…ack#3741) The current behavior when using functions such as invalidateQueries or setQueriesData is unexpected when objects with undefined properties are involved. A key containing an object with an undefined property is hashed without the undefined property, yet the property is considered in the partialDeepEqual function. This creates some confusing scenarios, as demonstrated in the discussion on TkDodo's blog <TkDodo/blog-comments#71 (comment)> and in the referenced issue This commit includes a failing test to demonstrate the expected behavior
I put the test with the queryCache tests since it seems to be the place closest to the problem |
I am concerned about allowing There are situations where I use |
Agree with @pschaub. Same issue here. |
this is what I did, not sure if there is a better way? export const useDataQuery = ({ id, endpoint, params = {} }) => {
const queryParams = buildQueryParams(params);
const queryKey = ["dataQuery", id, endpoint];
if (queryParams) {
queryKey.push(queryParams);
}
return useQuery({
queryKey,
queryFn: async () => await fetchData({ endpoint, queryParams }),
enabled: !!id,
});
} My issue was similar to others, where, even if I made queryParams undefined, it wasn't ignored as a key; so, then if I was using the |
Describe the bug
Query keys with object property set to undefined are not considered equal to missing property. Based on the docs, it should be the same: https://react-query.tanstack.com/guides/query-keys#query-keys-are-hashed-deterministically
Your minimal, reproducible example
https://codesandbox.io/s/react-query-trz8sx?file=/src/App.tsx
Steps to reproduce
Expected behavior
I expect both keys should invalidate the same records no matter of filter: undefined as mentioned in react-query docs.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
macOS v12.4
Chrome 103
react-query version
Both v3.39.1 and v4.0.0-beta.23
TypeScript version
v4.7.3
Additional context
No response
The text was updated successfully, but these errors were encountered: