Giter VIP home page Giter VIP logo

Comments (6)

vdvukhzhilov avatar vdvukhzhilov commented on July 20, 2024

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.

vdvukhzhilov avatar vdvukhzhilov commented on July 20, 2024

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.

TkDodo avatar TkDodo commented on July 20, 2024

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.

vdvukhzhilov avatar vdvukhzhilov commented on July 20, 2024

The default options only kick in when the key is not passed to useQuery, not when the value is set to undefined

@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:

  1. 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 line It 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 in defaultOptions.retry. Which falls into general semantics of term "default options".

  2. 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.

  3. 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 where retry is passed from spreaded argument. Yes, the way spreading argument works is by creating a variable which is undefined here and yes this way we "under the hood" pass retry: undefined. But, in our heads we consider this the same as not passing at all because we never write retry: undefined here.

  4. 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.

TkDodo avatar TkDodo commented on July 20, 2024

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.

vdvukhzhilov avatar vdvukhzhilov commented on July 20, 2024

exactOptionalPropertyTypes

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.