TanStack / query

🤖 Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.
https://tanstack.com/query
MIT License
42.45k stars 2.9k forks source link

useQuery() is only returning status 'success' if we call queryClient.fetchQuery() inside a React router loader #5689

Closed romulovalez closed 1 year ago

romulovalez commented 1 year ago

Describe the bug

When we use useQuery() in a component is only returning status 'success' if we call queryClient.fetchQuery() inside a React router loader, when it should be returning 'loading' or 'success', if we remove the queryClient.fetchQuery() from the loader them we got the normal behavior 'loading' or 'success'

Your minimal, reproducible example

https://codesandbox.io/p/sandbox/dark-http-q2zkgk?embed=1&file=%2Fsrc%2Froutes%2Fcontact.jsx%3A24%2C12

Steps to reproduce

  1. Navigate through the contacts (Dominik or Tanner Linsley)
  2. It only shows 'success' on the status (printed above the contact avatar)

Expected behavior

Status should be showing either 'loading' or 'success' because we're calling queryClient.fetchQuery() on the loader

How often does this bug happen?

Every time

Screenshots or Videos

https://github.com/TanStack/query/assets/1523575/377df12c-0cd0-4299-910b-90b4a8a79b05

Platform

Tanstack Query adapter

react-query

TanStack Query version

4.29.19

TypeScript version

5.1.3

Additional context

This can't be an intended behavior because we're getting new data with queryClient.fetchQuery(), and that should be reflected correctly on the status value.

TkDodo commented 1 year ago

Status should be showing either 'loading' or 'success' because we're calling queryClient.fetchQuery() on the loader

sorry, I don't understand the issue or the reproduction. When I open the app and click on one of the contacts, the status shows loading, and after that, it transitions to success. That is expected because your loader, in the current state, doesn't do anything - fetchQuery is commented out, so what happens is that the useQuery call triggers the QueryFunction

romulovalez commented 1 year ago

Ahh sorry!, the example was flawed, now it's fixed. Check the codesandbox again please.

TkDodo commented 1 year ago

so, what's the issue now? You call fetchQuery in the loader and return it, so you always see a success state.. that is expected. fetchQuery returns a promise. The react router loader takes this promise and awaits it, and it will only render your component once the promise is resolved ... That's how route loaders work

romulovalez commented 1 year ago

Ahhh!, React router awaits the promise and don't rerender until it's resolved, that's the reason I can't get the 'loading' on status unless I use react-router defer, my bad then 😅, this closes my issue, thanks for the help @TkDodo !