-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Allow passing function to useQuery
for finer-grained options
control
#9223
Allow passing function to useQuery
for finer-grained options
control
#9223
Conversation
useQuery
for finer-grained options
controluseQuery
for finer-grained options
control
89daec3
to
f22c54c
Compare
f22c54c
to
803d110
Compare
803d110
to
91d69e6
Compare
package.json
Outdated
"maxSize": "28.6kB" | ||
"maxSize": "28.95kB" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of this increase comes from #9459, where I have not updated the npm run bundlesize
limit yet. The actual net increase from this PR is +0.05kB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @benjamn, looks great! We'll need docs for this but we can add those after this is merged. Honestly your great PR description could probably just be dropped in the docs as is!
a0ce008
to
1d5218f
Compare
A pretty serious limitation of the
useQuery(query, options)
API is that it encourages passing a fresh bag ofoptions
as the second parameter every time the component (re)renders, potentially overwriting previous options from previous renders, with no way to tell which options should be taken merely as default values and which should override existing options. This ambiguity becomes especially problematic when options likeoptions.fetchPolicy
are updated elsewhere, but that work is undone the next timeuseQuery(query, { fetchPolicy: <original policy> })
is called:A more minor problem with the
useQuery
options API is that it's somewhat wasteful (in time and memory) to recreate a newoptions
object on every render, even if it will be safely ignored/discarded. The garbage still has to be collected, so it would be convenient (when it matters) to have a way to avoid recreating options unnecessarily.This PR introduces the option of passing a function as the second parameter to
useQuery
, which will be immediately invoked with the existing/current options (an empty object on first render), and should return new options (possibly including some unchanged existing options) to be merged with the existing options.Crucially, this functional style allows taking existing options into account when determining the new options to use, which means it's now possible to (re)use existing options as default values:
This function defaults to the current
options.fetchPolicy
andoptions.notifyOnNetworkStatusChange
to avoid overriding them on subsequent renders, but overridesonCompleted
unconditionally.Note that you do not need to worry about capturing/preserving
...rest
properties, as that happens automatically, thanks to merging the returned options with the existing options (mentioned above):However, if you really want to take control of things, you can skip this automatic merging by modifying the existing
options
object and returning it===
as given:If you only need to provide default values (a common use case) rather than forcing any options (like
onCompleted
), you could imagine implementing adefaultOptions
helper function that makes this a bit more ergonomic:I'll leave that implementation as an exercise for the reader, since this description is already running a bit long.
This PR is still a draft because I need to write tests and documentation, but I wanted to get it out there for discussion sooner rather than later.