query icon indicating copy to clipboard operation
query copied to clipboard

Error: No QueryClient set, use QueryClientProvider to set one

Open msobiecki opened this issue 1 year ago • 3 comments

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

  • OS: Linux
  • package manager: pnpm 8.15.9

Tanstack Query adapter

react-query

TanStack Query version

5.52.2

TypeScript version

5.3.3

Additional context

No response

msobiecki avatar Aug 27 '24 13:08 msobiecki

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([email protected]). 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.

TkDodo avatar Aug 27 '24 14:08 TkDodo

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.

msobiecki avatar Aug 28 '24 06:08 msobiecki

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:

  • make sure to use the same version across the monorepo
  • delete any cache folder or node_module in any repo
  • npm install and it should work

omarkhatibco avatar Aug 31 '24 20:08 omarkhatibco

Hi @TkDodo Thanks for the overview of potential reasons for this error. I am not using Next but rather using esbuild to build a standard React App. I've verified in package-lock that I am using only one version of react-query (5.66) and one version of react and react-dom (18.3.1). So, I don't see how I might get multiple versions of context. However, I do see this error.

I can confirm that your solution of importing and exporting the QueryClient and QueryClientProvider from the library and importing them in the App works but I don't think the explanation of having two separate instances of context as a result of different versions of React and/or react-query applies.

Perhaps there can be some other reason for ending up with two instances of context?

mcqj avatar Feb 04 '25 18:02 mcqj

I've verified in package-lock that I am using only one version of react-query (5.66) and one version of react and react-dom (18.3.1)

you can still have the same version installed multiple times, for example, if your shared library has a dependency on react / react-query rather than a peerDependency. It also varies between npm/yarn/pnpm/bun because they resolve these differently.

TkDodo avatar Feb 10 '25 15:02 TkDodo

HI @TkDodo Thanks again for getting back to me. I have gone through the dependency graph of the App and it does not look like there are any duplicates getting in the way. One thing that I did find was that I had a slightly earlier version of @tanstack/react-query-persist-client installed than react-query and that was resulting in two different versions of query-core being installed (5.66 and 5.45). I thought that was going to be the culprit but it didn't resolve the issue - I now only have a single copy of query-core installed.

mcqj avatar Feb 11 '25 18:02 mcqj

Hello, @msobiecki In monorepo @tanstack/react-query is duplicated in case if you are using shared packages even with peerDependencies the bundler resolves another version in the app folder from its own modules. My workaround for this is to export the module itself from your shared package and use it from there

Within your shared package export <QueryProvider /> const queryClient = new QueryClient(); <QueryClientProvider client={queryClient}>{children}</QueryClientProvider> Also export all hooks or functions that you are willing to use or export everything using : export * from "@tanstack/react-query";

Now you should have single version of the "@tanstack/react-query"

wa2elgomaa avatar Apr 11 '25 06:04 wa2elgomaa

I got this same error and search brought me here, I hope this fix helps someone This doesn't require changes to you library exports and your app imports

I got this same "No QueryClient set" error after upgrading from React Native 0.74.6 → 0.80.2 with React Query v5.

I have a shared library that uses useQuery, consumed by my mobile app inside the QueryClientProvider. Even though I set React Query as a peerDependency in the library and verified with yarn why @tanstack/react-query and yarn list @tanstack/react-query that only one version was installed, the error still happened.

metro.config.js:

const path = require('path');

const config = {
  resolver: {
    resolveRequest: (context, moduleName, platform) => {
      if (moduleName === '@tanstack/react-query') {
        return {
          filePath: path.resolve(
            __dirname,
            'node_modules/@tanstack/react-query/build/modern/index.js'
          ),
          type: 'sourceFile',
        };
      }
      return context.resolveRequest(context, moduleName, platform);
    },
  },
};

module.exports = config;

Environment

React Native: 0.80.2

React Query: 5.90.2

Metro: bundled with RN 0.80.2

This way, your app and libraries share the same QueryClient context instance. 🚀

naderalfakesh avatar Sep 24 '25 14:09 naderalfakesh

I got this same error and search brought me here, I hope this fix helps someone This doesn't require changes to you library exports and your app imports

I got this same "No QueryClient set" error after upgrading from React Native 0.74.6 → 0.80.2 with React Query v5.

I have a shared library that uses useQuery, consumed by my mobile app inside the QueryClientProvider. Even though I set React Query as a peerDependency in the library and verified with yarn why @tanstack/react-query and yarn list @tanstack/react-query that only one version was installed, the error still happened.

metro.config.js:

const path = require('path');

const config = { resolver: { resolveRequest: (context, moduleName, platform) => { if (moduleName === '@tanstack/react-query') { return { filePath: path.resolve( __dirname, 'node_modules/@tanstack/react-query/build/modern/index.js' ), type: 'sourceFile', }; } return context.resolveRequest(context, moduleName, platform); }, }, };

module.exports = config;

Environment

React Native: 0.80.2

React Query: 5.90.2

Metro: bundled with RN 0.80.2

This way, your app and libraries share the same QueryClient context instance. 🚀

u saved my life bro!!!!

1997roylee avatar Oct 13 '25 08:10 1997roylee

we also had this error and it turned out that our shared library that was wrapping the QueryClientProvider was build as CJS but our application was using useQuery from the ESM export of @tanstack/react-query. Then the context is also a different one between hook and provider. So always if someone else is having the same error make also sure that you are importing everyting from CJS or ESM and don't mix it.

jansepke avatar Nov 07 '25 12:11 jansepke

Thanks @jansepke - we had the same issue and it was not something that was easy to work around because the library was used elsewhere and needed to support both CJS and ESM. To me, it feels like a bug in the way the react-query library is being built. I feel like ultimately, it should resolve to the same context. We could work around it but it isn't ideal.

mcqj avatar Nov 07 '25 12:11 mcqj