Closed SoftMemes closed 1 year ago
it's hard to tell what went wrong without knowing how your monorepo setup is like. I use nx for my monorepo setup, with the following packages:
useQuery
, useQueries
and useInfiniteQuery
I don't face the issue you've described on what I have:
3.39.0
4.6.4
might be worthwhile for you to share the problem in a minimal reproducible setup
I appreciate that this isn't much to go on, but in general, what is the recommended method for providing custom hooks based on react-query in a library in terms of dependencies and configuration of the query client?
if you want a shared scope, meaning that the library uses the same context / client as the application that includes it, I would do it like you've described (I think):
lib
define react-query
as peerDependency
app
create the queryClient
and the QueryClientProvider
.the useQuery
calls in the lib should just pick up that client. If that's not the case, you likely have either two versions of react-query or two versions of react around.
if you want an isolated scope, I would take a look at the custom context feature for v4.
Any updates here? Is this still an issue?
Having same issue with turborepo monorepo setup, extracting queries to different package causes it.
@nctay can you link to an example repo that has the issue please?
Having the same issue as well with a NextJS pnpm monorepo setup, even after upgrading to react-query v4. Had to pass in defaultContext
to every single hook to get it to work. I'm also using next-transpile-modules
so that could be what's causing the issue.
It works flawlessly with a vite pnpm monorepo setup though.
I have same issue too
It's honestly not very helpful stating that you have the issue too without providing a minimal reproduction that we can look into. So far, no one has created a reproduction, so there is nothing I can look into. I'm gonna close this now, feel free to reopen once you can share a reproduction.
I faced this issue too, you need to check if have the equal version of react and react-query and both packages.
I faced this issue too, you need to check if have the equal version of react and react-query and both packages.
I do, still not working. I´m gonna have to learn publishing packages into npmjs and create reproduction case. It will take me some time, but I hope it will be worthy.
Hi,
Not a repro, and I'm travelling so will be a brief message from the phone, but I know at least what caused this now. Using yarn 3 with a pnpm style repo (this may apply to other setups but this is where I've seen it), a dependency will only be shared if it matches exactly. This means that the same version has to be resolved which is easy enough to guarantee with version ranges but also critically, the same dependencies need to have been resolved.
This interacts with in particular dev dependencies. If the project A dependends on library B, both which use a third party package C (for example react query), but A and B have direct dependencies in such a way that the dev dependencies of C are fulfilled by different versions, then A and B will see different instances of C.
The way to check this is to compare where the symlink for C is pointing in node modules for A vs B, the compare the node modules in turn for the instance of C used by A vs C used by B, and tweak dependencies of each until they match perfectly.
Having the same issue as well with a NextJS pnpm monorepo setup, even after upgrading to react-query v4. Had to pass in
defaultContext
to every single hook to get it to work. I'm also usingnext-transpile-modules
so that could be what's causing the issue.It works flawlessly with a vite pnpm monorepo setup though.
How did you do that? Facing same issue in next.js
@marissync The useQuery
hook accepts a context
option. Just pass in the defaultContext
exported by react query.
import { defaultContext, useQuery } from '@tanstack/react-query';
useQuery({ context: defaultContext });
@marissync The
useQuery
hook accepts acontext
option. Just pass in thedefaultContext
exported by react query.import { defaultContext, useQuery } from '@tanstack/react-query'; useQuery({ context: defaultContext });
Thank you, @petercpwong!!
Instead of asking for a failing reproduction wouldn't it be easier to provide a working one? I've tried what was suggested above but it's still failing in the production bundle. I'm using exact versions of react and react-query.
I can corroborate the issue with next-transpile-modules
.
Edit: @nctay @marissync @petercpwong I was able to resolve this issue by adding a resolve alias in my next.config.js
webpack settings:
// react-query causes issues with next-transpile-modules
// so we need to override the resolutions to prevent duplicates
webpack: (config, options) => {
if (options.isServer) {
config.externals = ["react-query", ...config.externals];
}
// this resolves to react-query/lib/index.js, so jump up two dirs
const reactQuery = path.resolve(require.resolve("react-query"), "../../")
config.resolve.alias['react-query'] = reactQuery
config.resolve.alias['react-query/devtools'] = path.resolve(reactQuery, "devtools")
return config;
}
I had the same issue when using react-query with @tanstack/react-query-devtools. I removed react-query and installed @tanstack/react-query and the issue was gone. Basically use both packages from @tanstack.
@system32uwu @SoftMemes @TkDodo I had the same issue. In this case for some reason pnpm installed two versions of react query (taken from the lockfile):
/@tanstack/react-query/4.3.4:
/@tanstack/react-query/4.3.4_sfoxds7t5ydpegc3knd667wn6m:
The problem went away when I changed peerDependencies
in all of my libraries that included react-query as a peer dependecies to include react as well, so changing from this:
"peerDependencies": {
"@tanstack/react-query": "^4.3.4"
}
To this:
"peerDependencies": {
"@tanstack/react-query": "^4.3.4",
"react": "^17.0.2",
"react-dom": "^17.0.2"
}
And after a pnpm install
, only one version is installed:
/@tanstack/react-query/4.3.4_sfoxds7t5ydpegc3knd667wn6m:
If someone wants to investigate it further, I created a minimal repository: https://github.com/szmarci/pnpm Master branch is the working one, fail branch is... well, the failing one.
This is the only difference in the source files (fail branch -> master branch):
And after install these are the lockfile
differences:
in a monorepo, using a lib within the repo. I'm using yarn
workspaces.
I added the lib as a peer dep, and added a webpack resolver in next.config.js
like this:
if (options.isServer) {
config.externals = ['@tanstack/react-query', ...config.externals];
}
const reactQuery = path.resolve(require.resolve('@tanstack/react-query'));
config.resolve.alias['@tanstack/react-query'] = reactQuery;
@TkDodo do you think the issue i linked above can come from esm support ? only one instance of @tanstack/react-query
is installed, zodios is declaring dependencies as peer dependencies for both react-query and react.
i checked installed packages, no duplicate.
seems related to webpack resolution, webpack seems to create two instance duplicate instances of react-query
in final build.
The bug was not happening on react-query
v3, that's why i suspect esm modules.
@jrea workaround works like a charm, but it's ugly to tell zodios users to resolve to such hacks. i know ts-rest
lib also has the same issue : https://github.com/ts-rest/ts-rest/issues/66
@TkDodo do you want me to open a new issue for this ?
@TkDodo i confirm the bug appeared in @tanstack/react-query
v4.3.0 and everything was fine on v4.3.2
I'll create an issue since i now have reproductible test case
@ecyrbe Do you have a link to the issue you created? I am also experiencing this issue
@rametta here : https://github.com/TanStack/query/issues/4346
But i closed it since i found that the issue is not in tanstack query but in webpack+next . The only way to make it go away is for your library to export esm + cjs packages
Interesting, I also made a reproduction repo https://github.com/rametta/react-query-v4-bug-repro but it's not using Next, it's using Vite. I will try to export both esm and cjs in my package, thank you
Yup confirmed it works now with ESM, I need to add these options to my typescript tsc compilation command --moduleResolution node --target es2015 --esModuleInterop
and defined both in my package.json, cjs in the main field and esm in the module field
@ecyrbe Actually I'm still having the issue with NextJS even though I'm building the ESM now. Vite is fixed, but NextJS is still throwing the same error. Any idea why? Anything special I need to define in NextJS?
@rametta Your package.json need to declare exports
.
Take a look at how i do it here: https://github.com/ecyrbe/zodios/blob/main/package.json
@ecyrbe That doesn't seem to help unfortunately. I got something semi working by specify "type": "module"
in my package.json and importing directly from the esm dir in my code, but I wish it was more automatic
There is an ugly workaround for next if all other things don't work (idea from @jrea ) : https://github.com/ecyrbe/zodios-express/blob/a237332b38cf0d8edb49edafb66c2d659a1d35f5/examples/next/next.config.js
Actually your previous comment did work, I just realized I needed to delete the Next cache (.next
dir) before rebuilding because I was still getting the old package.json 🤦
What a rollercoaster 😄 Thanks again
@rametta It is just useful in localhost. It fails when running in git action or docker. See here: https://github.com/Darkhorse-Fraternity/monad-stack/actions/runs/3538172759/jobs/5938774870#step:7:175
The solution that worked for me also worked in GitHub actions with a nextjs prod build consuming the package
I was able to reproduce the issue, which seems to be something with yarn v3 dependency resolution here: https://github.com/adairrr/missing-query-provider-repro
The interesting part of the issue is that running yarn why @tanstack/react-query
elicits only one version:
yarn why @tanstack/react-query
└─ dapp@workspace:packages/dappery
└─ @tanstack/react-query@npm:4.19.0 [ca7b3] (via npm:^4.19.0 [ca7b3])
https://github.com/vitejs/vite/issues/6780#issuecomment-1059677499
Make sure your library has all peer dependencies listed in your rollup config in your vite config file: build.rollupOptions.external
Just want to add here that I also had this problem with my tsconfig.json. Removing additional "lib" declarations solved it for me:
Previous
{ "compilerOptions": { "target": "ES5", "lib": ["ES2017", "ES7", "ES6", "dom"] }, }
New
{ "compilerOptions": { "target": "ES5" }, }
in a monorepo, using a lib within the repo. I'm using
yarn
workspaces.I added the lib as a peer dep, and added a webpack resolver in
next.config.js
like this:if (options.isServer) { config.externals = ['@tanstack/react-query', ...config.externals]; } const reactQuery = path.resolve(require.resolve('@tanstack/react-query')); config.resolve.alias['@tanstack/react-query'] = reactQuery;
Alias definitely works for this case.
React-query V4 update:
webpack: (config, options) => {
if (options.isServer) {
config.externals = ['@tanstack/react-query', ...config.externals]
}
config.resolve.alias['@tanstack/react-query'] = path.resolve(
require.resolve('@tanstack/react-query'),
'../../../'
)
return config
}
I'm really confused. If I add @tanstack/react-query
to my peer dependencies the only thing that happens is that I can't build my package anymore:
(typescript) Error: semantic error TS2307: Cannot find module '@tanstack/react-query' or its corresponding type declarations.
"peerDependencies": {
"@tanstack/react-query": "^4.22.0",
"react": "18.x",
"react-dom": "18.x"
},
I've even tried passing context
to my hooks but nothing, it's not working. I don't want people to have to install react-query
in their own project just to use my package.
Is there really no way to fix this without custom webpack configs or weird workarounds?
I don't want people to have to install
react-query
in their own project just to use my package.
Then you need to provide react-query as a dependency instead of a peer dependency. Peer dependencies are a declaration that the module using your module must have the dependency installed in order to use your module.
I don't want people to have to install
react-query
in their own project just to use my package.Then you need to provide react-query as a dependency instead of a peer dependency. Peer dependencies are a declaration that the module using your module must have the dependency installed in order to use your module.
I'm aware of that, but if I do that my package crashes when it's used because of the issue mentioned in the OP.
Just for the purpose of documenting it somewhere: We got the Error: No QueryClient set, use QueryClientProvider to set one
in a project too -- which happened because we had two react-query installations.
The setup with the problem:
- app/
--- package.json <- react-query installation
--- shared-library/
------ docs/
--------- package.json <- react-query installation
------ packages/
--------- a/
------------ package.json
--------- b/
------------ package.json
--------- c/
------------ package.json
The architecture used a git submodule to nest a shared library into various applications. Because of this issue here, we restructured the whole architecture to a monorepo structure to have the react-query installations not nested but side by side instead -- which causes a shared yarn.lock file in the end and a more robust dependency resolution.
The new setup without the problem:
- shared-library/ <- monorepo
--- app/
------ package.json <- react-query installation
--- docs/
------ package.json <- react-query installation
--- packages/
------ a/
--------- package.json
------ b/
--------- package.json
------ c/
--------- package.json
in a setup with several modules, make sure that all of them have their typescript compiler options (tsconfig.json) aligned in the following property:
"compilerOptions": { "module": "esnext" }
in case there is a mixture between "esnext" and "commonjs" module values, you will end up having several copies of the react-query library, leading to "Error: No QueryClient set, use QueryClientProvider to set one".
React-query V4 update:
webpack: (config, options) => { if (options.isServer) { config.externals = ['@tanstack/react-query', ...config.externals] } config.resolve.alias['@tanstack/react-query'] = path.resolve( require.resolve('@tanstack/react-query'), '../../../' ) return config }
This worked for us! But since our next.config.js
is at the root, we didn't have to add the path traversing.
Mine worked like this, so you don't have to guess how many levels up you have to go if the nextjs is the root:
webpack: (config, options) => {
// Fix issues with react-query:
if (options.isServer) {
config.externals = ['@tanstack/react-query', ...config.externals];
}
config.resolve.alias['@tanstack/react-query'] = path.resolve(
'./node_modules/@tanstack/react-query'
);
return config;
}
For anyone else having this problem when using Vite.
You need to add @tanstack/react-query to the vite.config.ts rollupOptions
rollupOptions: { external: ['react', 'react-dom', 'axios', '@tanstack/react-query'],
I appreciate that this isn't much to go on, but in general, what is the recommended method for providing custom hooks based on react-query in a library in terms of dependencies and configuration of the query client?
if you want a shared scope, meaning that the library uses the same context / client as the application that includes it, I would do it like you've described (I think):
- have the
lib
definereact-query
aspeerDependency
- have the
app
create thequeryClient
and theQueryClientProvider
.the
useQuery
calls in the lib should just pick up that client. If that's not the case, you likely have either two versions of react-query or two versions of react around.if you want an isolated scope, I would take a look at the custom context feature for v4.
We have this exact setup and are still running into this No QueryClient set, use QueryClientProvider to set one
issue with react-query v4. Figured that as long as the app that imports the component is wrapped in a QueryClientProvider it would be fine as you said but somehow it doesn't seem to be finding the right version of react-query from the lib component even though it has react-query and react as a peer dependency. Confirmed that there is only 1 version of @tanstack/react-query
in the yarn.lock file in the app repo.
Is converting our lib component to export as an ESM module really the only option we have to fix this?
I appreciate that this isn't much to go on, but in general, what is the recommended method for providing custom hooks based on react-query in a library in terms of dependencies and configuration of the query client?
if you want a shared scope, meaning that the library uses the same context / client as the application that includes it, I would do it like you've described (I think):
- have the
lib
definereact-query
aspeerDependency
- have the
app
create thequeryClient
and theQueryClientProvider
.the
useQuery
calls in the lib should just pick up that client. If that's not the case, you likely have either two versions of react-query or two versions of react around. if you want an isolated scope, I would take a look at the custom context feature for v4.We have this exact setup and are still running into this
No QueryClient set, use QueryClientProvider to set one
issue with react-query v4. Figured that as long as the app that imports the component is wrapped in a QueryClientProvider it would be fine as you said but somehow it doesn't seem to be finding the right version of react-query from the lib component even though it has react-query and react as a peer dependency. Confirmed that there is only 1 version of@tanstack/react-query
in the yarn.lock file in the app repo.Is converting our lib component to export as an ESM module really the only option we have to fix this?
See @donalnofrixion's answer above, it should solve your issue.
Both our next.js (webpack) app and react (vite) app faced this issue within our monorepo.
Here were the solutions for both
Vite: add a resolve alias to vite.config.ts
resolve: {
alias: {
'@tanstack/react-query': path.resolve(__dirname, './node_modules/@tanstack/react-query')
}
}
Next.js: add a resolve alias to next.config.ts
webpack: (config, { isServer }) => {
if (isServer) {
config.externals = ['@tanstack/react-query', ...config.externals];
}
config.resolve.alias['@tanstack/react-query'] = path.resolve(
'./node_modules/@tanstack/react-query'
);
return config;
},
Describe the bug
I have a monorepo with yarn 3 workspaces consisting of the following (as well as other components):
contracts
which uses Orval to create typed react-query hooks from OpenAPIui
, a next.js project that has a workspace dependency on contracts and is using above hooksThe only direct dependencies on react-query are through
contracts
, my UI project does not directly use react-query.I'm now running into a few issues to do with module resolution, and am not sure how much of this relates to yarn, workspaces, react-query, or next magic.
React-query cannot find QueryProvider
If I make react-query a peer dependency of
contracts
, then initializereact-query
in my next project (set a query provider, etc), then the hooks that use react-query under the hood fromcontracts
do not find the QueryClient. It appears to "see" its own version of react-query even though this is a peer dependency of contracts and I provide it as a direct dependency in ui.I am able to work around this by having
contracts
instead directly depend onreact-query
, and re-export the symbols from react-query (export * from 'react-query'). This appears to give the hooks in
contracts` access to the same react-query and the context / query provider is found.... or at least it was. Without any meaningful changes (I'm working on pinning down the exact change), I am no longer able to do it this way, as react-query now fails to find
react
. Inside the compiled code ofreact-query
, I am gettingReact
as an undefined symbol and this line blows upvar defaultContext = /*#__PURE__*/React.createContext(undefined);
iin react/QueryClientProvider.jsI appreciate that this isn't much to go on, but in general, what is the recommended method for providing custom hooks based on react-query in a library in terms of dependencies and configuration of the query client?
Your minimal, reproducible example
N/A
Steps to reproduce
Expected behavior
React-query can "see" the context and query provider wired up in the react DOM, even when using peer dependencies and the react-query library is provided as a dependency form the parent project.
How often does this bug happen?
Every time
Screenshots or Videos
No response
Platform
react-query version
3.39.0
TypeScript version
4.6.4
Additional context
No response