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
Hi 👋 we're rebuilding our front end app in react and we've been using the tanstack tools and really liking them. We've implemented our own logic on top of useQuery, though, because we want some different controls on how data is shown.
We're wondering if there's any interest in supporting our use case in the library.
The differences we want are:
Do not show stale data, suspend instead (we are only using suspense, but could be go to loading state instead of returning stale data for non-suspense)
Data fetched by a component should not change unless the query key changes. Or said differently, on a re-render do not read fresher data from cache.
We've had multiple implementations of this, our current one is below with some notes about where we have some awkward things. In short, we throw the promise ourselves if data is stale and implement our own logic in initialData to control which data is returned. But we are using useId as a cache buster. And there isn't a way for our queryFn to know if it's firing because of a refetch or a change to the query key so we've implemented that.
Are these things in part or full something that you'd consider supporting in the library?
import{hashQueryKey,useQuery}from'@tanstack/react-query'import{useEffect,useId,useRef}from'react'constuseSuspenseFetchQuery=({ queryClient, ...queryOptions})=>{// We're using useId as a cache buster, but it results in having 3 query keys for the same data. We want to write to the query key without a cache buster so we can use the cache, and we end up with two others because of the useId calls on first mount and subsequent mount after suspense resolves.constid=useId()constinternalQueryKey=queryOptions.queryKey.concat(id)// We track query hash because `queryFn` has no way of knowing whether it has been invoked because of a `refetch()` or a new query key.// During a `refetch()` we know we need to invoke the fetch function regardless of cached data staleness.constqueryHash=hashQueryKey(queryOptions.queryKey)constpreviousQueryHash=useRef(queryHash)constqueryHashHasChanged=queryHash!==previousQueryHash.currentconstinternalQueryFn=args=>{constqueryCache=queryClient.getQueryCache()constquery=queryCache.find(queryOptions.queryKey)// refetch() invokedif(query&&!queryHashHasChanged){returnquery.fetch()}else{// do the expected hook invocation with the shared query key// data will be cached on both shared query key and internal query keyreturnqueryClient.fetchQuery({
...queryOptions,queryFn: ()=>queryOptions.queryFn({ ...args,queryKey: queryOptions.queryKey}),queryKey: queryOptions.queryKey})}}const{ data, error, isRefetching, refetch }=useQuery({
...queryOptions,initialData: ()=>{constqueryCache=queryClient.getQueryCache()constquery=queryCache.find(queryOptions.queryKey)constisStale=query?.isStaleByTime(queryOptions.staleTime??1000)// if cached data with shared query key is fresh, use it as initial dataif(!isStale)returnquery?.state?.data},queryFn: internalQueryFn,queryKey: internalQueryKey,suspense: true})useEffect(()=>{previousQueryHash.current=queryHash},[queryHash])constqueryCache=queryClient.getQueryCache()constquery=queryCache.find(internalQueryKey)constisStale=query?.isStaleByTime(queryOptions.staleTime??1000)// do not return stale dataif(isStale&&isRefetching){throwqueryClient.fetchQuery({
...queryOptions,queryFn: internalQueryFn,queryKey: internalQueryKey})}return{ data, error, refetch }}exportdefaultuseSuspenseFetchQuery
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
Uh oh!
There was an error while loading. Please reload this page.
-
Hi 👋 we're rebuilding our front end app in react and we've been using the tanstack tools and really liking them. We've implemented our own logic on top of useQuery, though, because we want some different controls on how data is shown.
We're wondering if there's any interest in supporting our use case in the library.
The differences we want are:
We've had multiple implementations of this, our current one is below with some notes about where we have some awkward things. In short, we throw the promise ourselves if data is stale and implement our own logic in
initialData
to control which data is returned. But we are usinguseId
as a cache buster. And there isn't a way for our queryFn to know if it's firing because of a refetch or a change to the query key so we've implemented that.Are these things in part or full something that you'd consider supporting in the library?
Beta Was this translation helpful? Give feedback.
All reactions