Comments (6)
I believe the problem is in this line
And this one, too
undefined
values should be filtered out before assigning as they are essentially the same as providing no value at all and in that case should fallback to defaultOptions and than fallback to lib defaults
from query.
More advanced example
function useSomeQuery({ retry }: {retry?: number}) {
return useQuery({
retry
})
}
Here we suppose that you can omit retry when passing to useSomeQuery({})
. But due to spread of argument retry is passed as undefined
to useQuery
.
This would lead to some hours spent on debugging why default option is not applied here? I did not pass retry to my hook so logically it should fallback to default option.
from query.
This is on purpose. The default options only kick in when the key is not passed to useQuery
, not when the value is set to undefined
. A slight difference, but a difference nonetheless. we just object spread what you give us, so the fix is to not assign the key on your end. So instead of:
useQuery({
queryKey,
queryFn,
retry: someCondition ? 5 : undefined
}
do:
useQuery({
queryKey,
queryFn,
...(someCondition && { retry: 5 })
}
from query.
The default options only kick in when the key is not passed to
useQuery
, not when the value is set toundefined
@TkDodo Thank you for the clarification!
If that is by design, I would say that this should be pointed out in documentation.
Here is why:
-
I have not found any information in docs or your blog that would explain this particular behaviour (I mean falling back to lib defaults while setting option to
undefined
in query).
Except that is sortof implied here in lineIt is important to know that this will only work if your actual useQuery has no explicit retries set
, but even there the example is given that you could set your own retry for particular query when retries are turned off indefaultOptions.retry
. Which falls into general semantics of term "default options". -
When passing empty option ignores default options provided by you it is totally unclear because of semantics of term "default options", as passing your own default options usually implies that they are used instead of lib defaults.
-
Also passing
undefined
as an option value could be not as clear as in your examples. I have already shown how it could be view as "not providing" option here whereretry
is passed from spreaded argument. Yes, the way spreading argument works is by creating a variable which isundefined
here and yes this way we "under the hood" passretry: undefined
. But, in our heads we consider this the same as not passing at all because we never writeretry: undefined
here. -
Also, if following "we just object spread what you give us" there a discrepancy in that passing
undefined
as option skips user-passed default options but not the lib-defined default options. If the rule is "we just object spread what you give us" I would expect that no lib default would kick in either.
So considering all the points above I think it is better to explicitly state that passing undefined
option will lead to overwriting defaultOptions
one so that people would not spend time debugging 😄
from query.
If that is by design, I would say that this should be pointed out in documentation.
sure, feel free to amend the docs.
have not found any information in docs or your blog that would explain this particular behaviour
it's not like this question has come up a lot - this is the first time in 4 years for me 😅 . So I guess most people just don't pass something: undefined
to useQuery
.
I have already shown how it could be view as "not providing" option
Do you mean this example?
function useSomeQuery({ retry }: {retry?: number}) {
return useQuery({
retry
})
}
Because with exactOptionalPropertyTypes turned on, you couldn't pass retry:undefined
to your custom hook. { retry?: number }
is different from { retry: number | undefined }
, and since you clearly care about this distinction, I'd suggest turning that TypeScript feature on.
from query.
I agree that would help to prevent explicitly passing undefined
as value, but it not the case here.
The ones using this custom hook do not pass undefined like useSomeQuery({ retry: undefined })
, they do useSomeQuery({})
. It is the way speading objects works in JS that results in retry
variable inside useSomeQuery
being defined (with value undefined
).
Basically
function useSomeQuery({ retry }: {retry?: number}) {
return useQuery({
retry
})
}
And
function useSomeQuery(props: {retry?: number}) {
const retry = props.retry;
return useQuery({
retry
})
}
is the same.
from query.
Related Issues (20)
- Why for the first page only the `queryKey`'s `pagination` is a Proxy object and for the following pages not? HOT 2
- Solid-Query example returns repositoryQuery.data is undefined HOT 2
- Bug: Dependent Query doesn't work with solid-js SSR HOT 5
- Weird bug in useQuery's select HOT 1
- Bug: Cannot read properties of null (reading '__previousQueryOptions') HOT 4
- [Bug?]: Result type of combine works not as expected HOT 1
- Bug: Error when hydrating an query that threw error HOT 1
- useQuery() hook vulnerable to type errors HOT 1
- [svelte-query] `getQueryData`/`setQueryData` fail to infer query data type from `queryOptions` HOT 3
- ESLint Plugin: Flat Config Support HOT 2
- [react-query][Bug?]When invalidating useSuspenseQuery queries with invalidateQueries, the refetch process does not run. HOT 1
- useIsFetching stops tracking queries immediately HOT 1
- Typescript issue with queryOptions and usePrefetchQuery HOT 2
- No QueryClient set, use QueryClientProvider to set one
- Cannot read properties of null (reading 'useRef') with Vite Module Federation HOT 1
- docs: make the incompatibility of `skipToken` and `refetch` more detailed HOT 1
- "React Example: Nextjs Suspense Streaming" doesn't work HOT 1
- `useSuspenseQuery` does not retry after `fetchQuery` returned an error HOT 4
- invoking `suspense()` with `enabled: false` will wait infinite while ssr HOT 3
- Vercel build error when using HydrationBoundary HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from query.