useReadQuery networkStatus not changing

I’m currently using TanStack Router in conjunction with Apollo Client. I’ve got a route structure like the following:

export const Route = createFileRoute("/_auth/_onboarding/home/clients")({
  component: IndexList,
  validateSearch(search) {
    return ClientIndexSchema.parse(search);
  // eslint-disable-next-line sort-keys-fix/sort-keys-fix
  loaderDeps({ search }) {
    return search;
  // eslint-disable-next-line sort-keys-fix/sort-keys-fix
  async loader({ context, deps }) {
    return context.client
      .preloadGraphQLQuery(CLIENT_INDEX_QUERY, {
        variables: { searchTerm: deps.q },

Then in my component I’m using useReadQuery(), but the networkStatus doesn’t seem to change when my URL params change. Just wondering if I’m expecting something to happen differently here?

function IndexList() {
  const dataRef = Route.useLoaderData();
  const search = Route.useSearch();
  const { data, networkStatus } = useReadQuery(dataRef);
  //                     ^? this doesn't seem to change when URL params trigger a new loader fetch

useReadQuery suspends your component every time a query is made (so a top Suspense boundary would show) - if your component renders, it will always have loaded a valid result, so I wouldn’t really expect to see any networkStatus other than ready.

What are you seeing and what would you expect instead?

Currently I’m seeing what you describe in that it sets the network status to ready and that value is unchanged even after triggering the preloadQuery to be executed again when the search params change.

I think I was expecting that the preload would cause the network status to reflect that it was performing a new query. I moved to the use of .toPromise() to avoid the suspense boundary from being thrown to keep the current data while an updated loader query is occurring and assumed that I could leverage the network status to reflect a visual difference between refetch, loading etc.

You have two independent queryRefs for two independent queries here - loading the new one will not make the old one go into a loading state.

With the use of .toPromise you currently have, the new queryRef will only be available to your component after the query has resolved.

You could introduce a pendingComponent for your route here, but your old route will only see the old query.

Ah. Guess I’ll just move my loading state into the component with useQuery so I have more fine grain control over the behaviour.

Thanks for the clarification. That’s super helpful to understand. I totally misunderstood the flow of data from the loader here.

I guess this is the beauty of Apollo is I’m able to move the query up/down the hierarchy depending on my needs.