-
Notifications
You must be signed in to change notification settings - Fork 787
Add useQuery
lazy mode to defer query execution
#3214
Conversation
Initial work to support deferring `useQuery` execution until some point in the future (after `useQuery` has been initialized). If a `lazy` option is set to a boolean, `useQuery` will return a tuple instead of a result object. The first position of the tuple is the standard query result object, and the second position is a function that can be triggered to kickstart the normal `useQuery` query cycle. If `lazy` is `true`, the initial query result with have a `loading` status of `false`, and a `data` value of `undefined`. This will only change after query execution has been triggered using the delayed start function. If `lazy` is `false`, a tuple is still returned, but `useQuery` will still fire immediately (similar to calling `useQuery` without a `lazy` option). Fixes apollographql/apollo-feature-requests#119.
Thanks for accepting my suggestion and working on it. At first glance, it feels somewhat strange having a different return shape based on the existence of a boolean option value. Good thing is that we can name the On the point of |
We might want to support other options, but we'll start with these.
Another important aspect regarding the |
I wonder, why not to have the same order of variables in that tuple as the |
Yea, just commented on useMutation change which I don't think is actually correct. However, for the |
Haha - we've struggled with this as well; there are pros/cons to both approaches for sure. For now we're going to go with the current approach of results first, function second (and we'll adjust if/as needed). |
Is `true` by default unless running `useQuery` in lazy mode. In lazy mode `called` will only be `true` after the lazy mode execute function has been called.
I'd say better api would be like const [shouldFetch, setShouldFetch] = useState(false)
useQuery(GET_ROCKET_INVENTORY, {
enabled: shouldFetch,
}); and then it'll not get executed until |
@pie6k That's already there with |
Wouldn't it be better to have a seperate hook for this? It feels a bit odd that the return types changes based on the parameters passed to the hook. A hook like |
@rovansteen Considering its a totally optional feature and you must explicitly specify that option, there is no benefit of separating to an extra hook. Besides, you can always make your own |
@rovansteen I agree it is a bit strange, but I was interested in saving a few extra bytes. I'll defer to whichever approach @benjamn prefers, during code review. |
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.
As anticipated, I would be happier with a separate useLazyQuery
method, instead of passing { lazy: true }
to useQuery
and having to use type inference to sort out the correct return type.
As of 157339f, const [{ loading, data }, execute] = useLazyQuery(GET_ROCKET_INVENTORY); |
I agree it's probably more coherent to have a separate hook for that. Once again about the order of arguments in the tuple. This is a similar case to Wouldn't be also desirable to get the Promise with a result from Does a |
All great points @FredyC, and now that we have a separate hook for this, these are easier to implement. I'll adjust - thanks! |
@FredyC Returning a promise with the lazy execution loaded result will require a bit more refactoring than we want to tackle before the RA 3 launch. It's a good idea, but we'll have to schedule it for a future point/minor release. |
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.
Looking good!
Enabling/disabling lazy mode is no longer handled by passing an option into the `useQuery` hook. The `useLazyQuery` hook can now be used when lazy mode is preferred. This gets us away from using type inference to decide on the return type of `useQuery`.
This caused a problem recently where bundle changes weren't being picked up properly by other packages in the monorepo.
Since running a query using `useLazyQuery` requires calling the lazy execution function, this commit moves the function into the first position of the returned tuple.
Initial work to support deferring
useQuery
execution until some point in the future (afteruseQuery
has been initialized).If alazy
option is set to a boolean,useQuery
will return a tuple instead of a result object. The first position of the tuple is the standard query result object, and the second position is a function that can be triggered to kickstart the normaluseQuery
query cycle.Iflazy
istrue
, the initial query result with have aloading
status offalse
, and adata
value ofundefined
. This will only change after query execution has been triggered using the delayed start function (execute
in the following example):Iflazy
isfalse
, a tuple is still returned, butuseQuery
will fire immediately, just like callinguseQuery
without alazy
option. So these are the same:UPDATE
The above is no longer accurate.
useQuery
will always run the defined query, butuseLazyQuery
can be used to defer query execution. It works like:Fixes apollographql/apollo-feature-requests#119.
TODO:
skip
called
option (likeuseMutation
)execute
variables