-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
ContextSharing not working for different modules #2810
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
right, I think you'd need a |
Thanks for the quick reply! Actually I found the issue: I had a higher version of React-Query in my peer dependencies for my npm module. That's why it wasn't using the same version in both projects. Took me a while to figure that out... |
okay cool, but maybe I'm not fully understanding |
Sure thing! The library has Of course, if the peer deps version does not match with the consumer version, webpack will use two different instances for both of them, which is why the context was not shared 😅 |
@reh2ur I'd be curious to have more details as to how you fixed this, since I'm in a very similar situation. We have a “shared library” which is imported as a package in various projects within a monorepo. I‘m trying to transfer what we call the Similarly to your situation, we have Did you happen to do anything else other than making sure that the versions matched? |
this is exactly what we're trying and this is still happening for me as well @vsylvestre and @reh2ur, details here: #3697 I checked the |
you'd need to provide a reproducible example of some sorts please. |
I was able to force both MFEs to use the same
|
I do think context sharing is broken and that's because the QueryClientSharingContext is created across all instances of react-query and so the sharing context itself isn't shared. That context is the way the value passed in for That's how useQueryClient knows to use context sharing |
I'm honestly pretty unsure what contextSharing is and what it's supposed to be doing. Is it necessary / useful to anyone? Isn't the new feature in v4 enough where you can pass a custom context around? If so, I would be in favour of deprecating it ... |
yeah I'm not sure. What's weird is that it's not absolutely clear how you'd use either feature. Because providers are rendered at the top of the tree, in a microfrontend setup every separate module would still have to be passed the context, check if a context was already provided and if not, render a provider. This could be done very similarly without passing import React from 'react';
import { QueryClient, QueryClientProvider, useQueryClient } from '@tanstack/react-query';
type ProviderProps = {
children: React.ReactNode;
client: QueryClient;
};
export default function Provider({ children, client }: ProviderProps) {
try {
useQueryClient();
return children;
} catch (_e) {
return (
<QueryClientProvider
// if client instance types match, then we know the same version of react-query got loaded
// otherwise just create a new client for this module
client={client instanceof QueryClient ? client : new QueryClient()}
>
{children}
</QueryClientProvider>
);
}
} with context getting passed, it would look very similar: import React from 'react';
import { QueryClient, QueryClientProvider, useQueryClient } from '@tanstack/react-query';
type ProviderProps = {
children: React.ReactNode;
client: QueryClient;
context: React.Context<QueryClient | undefined>;
};
export default function Provider({ children, client, context }: ProviderProps) {
try {
useQueryClient({ context });
return children;
} catch (_e) {
return (
<QueryClientProvider
client={client instanceof QueryClient ? client : new QueryClient()}
// if a client is provided from above but none exists in context and client instance types match
// add it to the provided context
context={client instanceof QueryClient ? context : undefined}
>
{children}
</QueryClientProvider>
);
}
} and so I'm not exactly sure what the purpose of Edit the non-context example does however break react query devtools |
So like i said on V5 discussion context sharing is used in the context of microfrontends. Big picture here : Now context isolation is an option if handled by each microfrontend to override the default react-query context instance. So you need to either:
|
@ecyrbe I'm not entirely sure how you've setup microfrontends, but why wouldn't the hosting application just create the QueryClient and the Provider, and it would then be picked up by the microfrontends when they call Are the microfrontends mountings themselves to different roots? If so, creating the context and passing it to the microfrontends as shown in the custom-contexts docs should work? Albeit a bit more boilerplate as every call to useQuery / useQueryClient would need to use that context ... I just have the feeling that taking the context and putting it onto the window object is also a bit dirty. |
|
I understand, make sense.
That i don't understand so much. If I want to share a QueryClient between MFEs, why is that not the responsibility of the hosting app? It doesn't need to know about react - it just needs a dependency to Isn't it in general a bit magical that the first MFE that mounts decides what the context is? Can that not lead to random behaviour? |
The issue seems to be with the context setup more than query client instanciation. So, If you don't want to maintain this i'll find a way to do the necessary on my app. Don't worry. |
@ecyrbe if there is a legit use-case for microfrontends that is not easily solvable otherwise, this could in fact be a good feature. It's just not clear to me (and others) what it does exactly. You've done a good job explaining it :) what I still don't quite understand is: We are not sharing the |
Oh, maybe i'm misstaken too. Because i thought that using shared context was sharing QueryClient. Can one context handle many QueryClients ? |
no 😅. In order to share data, you'd need to use the same queryClient |
I should take a look at the current code implementation then. Because, i have shared context setup on all mfe, doing nothing special with query client and expecting it to use the first one instanciated. at least last time i cheked, that's what i thought was happening. |
Here is a quick codesandbox reproduction that renders the same App twice with two different mountpoints. Each App gets a https://codesandbox.io/s/tender-dust-z7695p?file=/src/index.jsx As you can see in the If you go the devtools and log
|
Hey @TkDodo Sorry, this is going back a year. We have a scenario where we do want to share the data between both Apps. Any idea how this can be achieved? |
In v5, you can pass a queryClient directly to all hooks as second argument. You can "share" that client however you want to, but we are not doing anything like that. |
We basically have a legacy Rails app and have replaced the traditional rails views with React based pages instead. However, we're using
Because each of these is a separate app, they all create their own I know this is not your problem but I was wondering if you had any thoughts? Share the client via local storage? Use the I guess one more simple way would be to import
|
yep this |
Describe the bug
When using the
QueryClientProvider
in an npm package and requiring the query client viauseQueryClient
in the consumer app, I am always getting the following error:It seems like the logic for getting the shared context is broken.
Expected behavior
Using the
useQueryClient
should check for the sharedReactQueryClientContext
and use it if existing.Additional context
With #1912 the context sharing was disabled by default, and seems to have been disabled at all.
It seems like the
QueryClientSharingContext
is always false, as it is initialized with that value:https://github.com/tannerlinsley/react-query/blob/05a8057e2be64915d2a12b716d8131f113598dbd/src/react/QueryClientProvider.tsx#L12
https://github.com/tannerlinsley/react-query/blob/05a8057e2be64915d2a12b716d8131f113598dbd/src/react/QueryClientProvider.tsx#L34
Shouldn't the context be initialized with whether there is a shared context or a boolean value, passed to the
useQueryClient
hook?The text was updated successfully, but these errors were encountered: