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.36k stars 2.89k forks source link

Error: No QueryClient set, use QueryClientProvider to set one #7965

Open msobiecki opened 2 months ago

msobiecki commented 2 months ago

Describe the bug

When using the @tanstack/react-query v5 library within a Turborepo monorepo structure, specifically inside a shared library, the following error is thrown:

Error: No QueryClient set, use QueryClientProvider to set one.

Your minimal, reproducible example

https://github.com/msobiecki/react-query-repro

Steps to reproduce

Reproduction Steps:

  1. Set up a Turborepo monorepo with multiple packages, including a shared UI or API library.
  2. Install @tanstack/react-query v5 in the shared package.
  3. Import and use React Query hooks or components (e.g., useQuery) from the shared library in any consuming application within the monorepo.
  4. Run the application.

Demo:

  1. pnpm install && pnpm run dev

Expected behavior

The @tanstack/react-query library should function as expected within the shared library.

How often does this bug happen?

Every time

Screenshots or Videos

image

Platform

Tanstack Query adapter

react-query

TanStack Query version

5.52.2

TypeScript version

5.3.3

Additional context

No response

TkDodo commented 2 months ago

This issue has been filed many times. I know it seems that way, but it's not a react-query bug/issue. useQuery, under the hood, uses react context to read the nearest QueryClient. If the context of the consumer is not the same as the context of the producer, they don't "see" each other.

The most likely scenario is multiple versions of react-query or react in your codebase. I checked the lockfile, it doesn't seem that way, but nextjs comes with it's own version of React19, even if you say you use React18.

Further, pnpm scopes the versions along with peerDependencies, so the actual version you're using is version: 5.52.2(react@18.3.1). If a consumer doesn't use the exact same version+peerDependencies, pnpm will create a second instance, which means a "new context" instead of a shared context.

This problem is the same for all libraries that use react context to share some static instance (in our case, the QueryClient).

If I'm correct, just not using next but e.g. a simple vite app for the reproduction where no magic with react versions is going on should make it work. I'm personally using an nx monorepo + vite with consumers/producers in different packages in the same app and it works just fine.

For your specific situation, I would recommend to have the shared lib not only expose the custom hooks, but also the queryClient and the QueryClientProvider. Then, the app can render the QueryClientProvider with the client it gets from the app.

In the isolated, shared package, you can also pass the queryClient as second argument to useQuery. This would take precedence over reading the value from context.

msobiecki commented 2 months ago

This is a bit strange, the previous versions (currently based on 4.2.3) that I relied on handled it without any problems.

While sample is quite simple, with more complex library structures, it's hard for me to imagine pushing the queryClient property specifically through the entire library, to the nested e.g. useQuery.

By the way, it would be good if some example appeared in the documentation, with examples of use in monorepo or shared libraries, because unfortunately there are none, which is probably why this thread comes back like a boomerang.

omarkhatibco commented 2 months ago

I have the same issue with Tanstack Router, after I updated to the latest version

Edit: It's correct what @TkDodo, if you have multiple different version of react query it will broke.

step to fix: