You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I like to keep the queryFn as generic as possible to be able to leverage the cache properly and prevent cache collisions of different requests.
// This is safeuseQuery('/todos',fetch)
// This can cause bugs easieruseQuery('/todos',()=>fetch('/todos'))// Query key and fetched data can get out of sync due to typos.// This query would accidentally share cache with the first one.useQuery('/todos',()=>fetch('/todo'))// Custom fetcher can be modified by devs who don't know about implicit connection.// This query would also accidentally share cache with the first two.useQuery('/todos',()=>fetch('/todos?filter=unread'))
To prevent these kinds of bugs I think it's important that the queryFn should be able to stay generic and not incentivise to create a custom queryFn per hook call.
Problem
For both usePaginatedQuery and useInfiniteQuery it's not possible to use a generic queryFn like fetch. The reason is that the page/cursor is passed as last argument to the queryFn.
useInfiniteQuery('/todos',// It's not possible to use a generic queryFn because the function needs to be aware of the cursor(key,cursor)=>fetch(`/todos?after=${cursor}`),{getFetchMore: (lastPage)=>lastPage.nextPageCursor})
I might be able to use one generic queryFn for all paginated and cursor-based queries, but that's only possible if pagination is consistent across all endpoints and I'm only targeting one single backend.
The problem here is that queryFn can't be generic anymore and is therefore subject to the issues described in the Background section.
Possible solution
To be able to keep fetch as the queryFn, we would need to transform the queryFn parameters to include the cursor. This could be solved with a callback which receives the query key passed to usePaginatedQuery/useInfiniteQuery and returns the parameters which should be passed to the queryFn.
This change would be breaking and therefore only possible in a major release. What do you think about it?
Additional ideas
TypeScript issues due to complex queryFn signature in usePaginatedQuery and useInfiniteQuery could be solved by this
queryKey in applyCursor function could be the exact query key passed to the hook. This would further simplify the function signature and make life easier for TypeScript users.
In the documentation there are lots of examples where custom queryFn per hook call is used. If you agree with my issue from the Background section, we could change those.
Modifying the query key with applyCursor might simplify how queries are cached. I'm not familiar with the caching mechanism, but maybe caching the results based on the key returned by applyCursor might remove special query key handling for usePaginatedQuery and useInfiniteQuery because the key now behaves exactly the same as in the useQuery hook.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
For simplicity reasons, let's define the
fetch
function used here asBackground
I like to keep the
queryFn
as generic as possible to be able to leverage the cache properly and prevent cache collisions of different requests.To prevent these kinds of bugs I think it's important that the
queryFn
should be able to stay generic and not incentivise to create a customqueryFn
per hook call.Problem
For both
usePaginatedQuery
anduseInfiniteQuery
it's not possible to use a genericqueryFn
likefetch
. The reason is that the page/cursor is passed as last argument to thequeryFn
.I might be able to use one generic
queryFn
for all paginated and cursor-based queries, but that's only possible if pagination is consistent across all endpoints and I'm only targeting one single backend.The problem here is that
queryFn
can't be generic anymore and is therefore subject to the issues described in the Background section.Possible solution
To be able to keep
fetch
as thequeryFn
, we would need to transform thequeryFn
parameters to include the cursor. This could be solved with a callback which receives the query key passed tousePaginatedQuery
/useInfiniteQuery
and returns the parameters which should be passed to thequeryFn
.Internally, the cursor could be applied like this:
We could even reduce those two callbacks into a single one.
This change would be breaking and therefore only possible in a major release. What do you think about it?
Additional ideas
queryFn
signature inusePaginatedQuery
anduseInfiniteQuery
could be solved by thisqueryKey
inapplyCursor
function could be the exact query key passed to the hook. This would further simplify the function signature and make life easier for TypeScript users.queryFn
per hook call is used. If you agree with my issue from the Background section, we could change those.applyCursor
might simplify how queries are cached. I'm not familiar with the caching mechanism, but maybe caching the results based on the key returned byapplyCursor
might remove special query key handling forusePaginatedQuery
anduseInfiniteQuery
because the key now behaves exactly the same as in theuseQuery
hook.Related
Beta Was this translation helpful? Give feedback.
All reactions