diff --git a/.changeset/fix-use-queries-prefetch-in-render.md b/.changeset/fix-use-queries-prefetch-in-render.md new file mode 100644 index 00000000000..e6a007712bb --- /dev/null +++ b/.changeset/fix-use-queries-prefetch-in-render.md @@ -0,0 +1,5 @@ +--- +'@tanstack/react-query': patch +--- + +Add experimental_prefetchInRender support to useQueries so that React.use(promise) resolves correctly diff --git a/packages/react-query/src/useQueries.ts b/packages/react-query/src/useQueries.ts index de179837a5f..4e07b0734df 100644 --- a/packages/react-query/src/useQueries.ts +++ b/packages/react-query/src/useQueries.ts @@ -4,6 +4,7 @@ import * as React from 'react' import { QueriesObserver, QueryObserver, + isServer, noop, notifyManager, } from '@tanstack/query-core' @@ -19,6 +20,7 @@ import { ensureSuspenseTimers, fetchOptimistic, shouldSuspend, + willFetch, } from './suspense' import type { DefinedUseQueryResult, @@ -324,5 +326,32 @@ export function useQueries< throw firstSingleResultWhichShouldThrow.error } + // Handle experimental_prefetchInRender for each query that has it enabled + if (!isServer) { + const observers = observer.getObservers() + optimisticResult.forEach((result, index) => { + const opts = defaultedQueries[index] + if ( + opts?.experimental_prefetchInRender && + willFetch(result, isRestoring) + ) { + const queryObserver = observers[index] + const query = client + .getQueryCache() + .get(opts.queryHash) + + const promise = !query?.state.dataUpdateCount + ? // New cache entry: fetch immediately to ensure .promise is resolved even if the component is unmounted + fetchOptimistic(opts, queryObserver!, errorResetBoundary) + : // Existing cache entry: subscribe to the "cache promise" to finalize the currentThenable once data comes in + query?.promise + + promise?.catch(noop).finally(() => { + queryObserver?.updateResult() + }) + } + }) + } + return getCombinedResult(trackResult()) }