reactjsreact-querytrpc

tRPC/react-query, component doesn't receive results of any useQuery until all queries are complete


I can't figure out why react query (in this case wrapped by tRPC) is behaving this way.

Say we have a component that makes two API calls to get some data.

export const MyComponent = () => {

  const sample1Result = api.myRouter.sampleRequest1.useQuery()
  const sample2Result = api.myRouter.sampleRequest2.useQuery()

  return (
    <div>
      <div> {sample1Result.data ? "Query 1 returned" : "Query 1 waiting"} </div>
      <div> {sample2Result.data ? "Query 2 returned" : "Query 2 waiting"} </div>
    </div>
  )
}

And on the backend, we have two API calls (configured in a tRPC router), which in this example are forced to take 5 seconds and 10 seconds respectively.

 sampleRequest1: publicProcedure
     .query(async () => {
        console.log(`Called sampleRequest1`)
        await new Promise(resolve => setTimeout(resolve, 5000))
        console.log(`Returning from sampleRequest1`)
        return "Hello 1"
    }),
    
sampleRequest2: publicProcedure
    .query(async () => { 
        console.log(`Called sampleRequest2`) 
        await new Promise(resolve => setTimeout(resolve, 10000))
        console.log(`Returning from sampleRequest2`)
        return "Hello 2"
    }),

What happens is, both queries are fired off immediately as expected. But then, in the component, I don't see "Query 1 returned" after 5 seconds and "Query 2 returned" after 10 seconds as expected. Instead, they only both update the component after 10 seconds when both API calls are complete. What is causing react-query to not handle concurrent queries finishing at different times to immediately update the component?

From the react-query and tRPC docs parallelism seems to be implied, and it is in fact calling the APIs in parallel. But it's no good if I don't get the results of each query immediately. Fwiw, this issue still happens if the useQueries are in different React components, or even if I use parallel mutations with Promise.all.


Solution

  • I found the answer to my own question. tRPC automatically batches requests. Normally I guess that's helpful, but not in my case.

    Here is the guide to disable batching, which has the expected outcome of making each request send and respond independently. https://trpc.io/docs/v9/links#disabling-request-batching