query: Unable to use more than one apps with QueryClientProvider on page
Describe the bug
In my scenario I need to host more than one react application on one page.
Each of app uses react-query v3, app wrapped with QueryClientProvider (I can reproduce it with CRA apps with just your “overview” sample code (https://codesandbox.io/s/github/tannerlinsley/react-query/tree/master/examples/simple)).
When I open page with these apps, only one of them running fine, and others fails with error:
No QueryClient set, use QueryClientProvider to set one
Maybe it’s because of using window.ReactQueryClientContext for context storage of app, what makes impossible to use many react-query context on one page with many apps (https://github.com/tannerlinsley/react-query/blob/master/src/react/QueryClientProvider.tsx#L9).
If I use just one app with many QueryClientProviders it’s works ok.
If you can suggest any workarounds for this issue, I will appreciate it. Thank you.
To Reproduce Steps to reproduce the behavior:
- Build 2 apps with example from here: https://codesandbox.io/s/github/tannerlinsley/react-query/tree/master/examples/simple
- Host these 2 apps with one html page (I just build two CRA apps and then add div and scripts from one app index.html to another).
- Serve this overall html (I did just serve -s build).
- See error. First app crashes, but second runs fine.
Expected behavior Every separate apps runs without react-query related errors and with react-query functionality.
Additional context I tried to add some timeout for render of second app, and it’s works but only for the first serve of html. Than, after page reload errors returns.
setTimeout(() => {
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("app2")
);
}, 1000);
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 8
- Comments: 40
It’s my birthday today, so I’m going to put a pin in this one and check back tomorrow. If anyone can nail down the reproduction any better, let me know!
I’ve got a potential fix here: #1805, but could use some extra validation/testing outside of our unit tests (which are all single-module context 🤷♂️ 😂 )
Hi, not adding much to the discussion, except for +1’ing the issue. We are also in a similar situation. We are evaluating RQ and are pretty impressed with it, but this use-case is kind of a show-stopper for us to continue. Hopefully, the fine guys behind RQ will come up with a solution soon 👍
@tannerlinsley we are also in the process of using multiple microfrontends on the same page, each one using / wanting their own QueryClientProvider, son I’m sure we’ll see the issue as well quite soon.
I haven’t fully understood the need for attaching to the window yet, but if we need that, I think the optional context name suggested by @NZainchkovskiy would work. It could alternatively also maybe be a name/id field on the QueryClient itself.
I have the same issue, we have a rails app that we are slowly moving over to react and this has been a problem since we upgraded to v3. Love the library, let us know what we can do to help!
I took a quick look, but not really sure how to achieve this. if we pass a flag or a custom context name to the query client constructor or to the
QueryClientProvideras a prop, we can set this up on the window, but every time we calluseQueryClient, we’d need to know the name before we get the queryClient. But we don’t have the name yet because we have not gotten the client yet. A bit of a chicken-egg problem.For my understanding: What happens if I mount the same microfrontend twice on the same page? Will they share the same QueryClient and QueryCache? From what I can tell, we are “just” sharing the same instance of context, but I’m having a hard time grasping what that means or what that does exactly…
Thank you so much! I tested it and now it’s works like a charm!
Again, React contexts are not matched by display name or any string matching. They are matched with a reference equality comparison.
So let’s say you have a react query dep bundled in one app and another react query dep bundled in another. These two different bundles will not resolve the same React Query module instance when loaded in same browser instance (unless you’re using module federation, which is still very early and uncommon) and thus, you will have 2 separate context instances running simultaneously. The only ways to share and use React contexts across module boundaries are:
Tracked it down to: https://github.com/tannerlinsley/react-query/pull/1360/commits/e8a22e914101fb35b48f6b335ba73644417583dd .
Looks like this was added to support multiple react query versions in one app but I don’t know the specifics.
I think simpliest solution will be adding optional property to QueryClientProvider and using it for placing context to window. So for such edge cases one can use unique window property for each application.
There is quick and dirty concept. I think it’s far from ideal and maybe @tannerlinsley will suggest something better, but for the idea: