apollo-client
apollo-client copied to clipboard
Invariant Violation: Could not find "client" in the context or passed in as an option. Wrap the root component in an <ApolloProvider>, or pass an ApolloClient instance in via options.
Intended outcome:
I was hoping to connect with the Hasura server using Apollo Actual outcome:
Got the error response:
Invariant Violation: Could not find "client" in the context or passed in as an option. Wrap the root component in an <ApolloProvider>, or pass an ApolloClient instance in via options.
How to reproduce the issue:
I have a very simple setup.
- Followed the react native setup for Typescript from : https://reactnative.dev/docs/typescript
- Modified
App.tsx
to:
import React from 'react';
import { StyleSheet, ScrollView, Text, FlatList } from 'react-native';
import { ApolloProvider, ApolloClient, useQuery } from '@apollo/client';
import makeApolloClient from './apollo';
import gql from 'graphql-tag';
// import { useQuery } from '@apollo/react-hooks';
export const FETCH_TODOS = gql`
query {
todos (
order_by: {
created_at: desc
},
where: { is_public: { _eq: false} }
) {
id
title
is_completed
created_at
is_public
user {
name
}
}
}
`;
const App: () => React.ReactNode = () => {
let [client, setClient] = React.useState({} as ApolloClient<any>);
client = makeApolloClient("eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik9FWTJSVGM1UlVOR05qSXhSRUV5TURJNFFUWXdNekZETWtReU1EQXdSVUV4UVVRM05EazFNQSJ9");
setClient(client);
const { data, error, loading } = useQuery(
FETCH_TODOS,
);
return (
<ApolloProvider client={client}>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.scrollView}>
<FlatList
data={data.todos}
renderItem={({ item }) => <Text>{item}</Text>}
keyExtractor={(item) => item.id.toString()}
/>
</ScrollView>
</ApolloProvider>
);
};
const styles = StyleSheet.create({
scrollView: {
backgroundColor: "white",
}
});
export default App;
- Apollo function import from
apollo.ts
:
import {
ApolloClient,
InMemoryCache,
NormalizedCacheObject,
createHttpLink
} from '@apollo/client'
export function makeApolloClient({ token }: any): ApolloClient<NormalizedCacheObject> {
// create an apollo link instance, a network interface for apollo client
const link = createHttpLink({
uri: `https://hasura.io/learn/graphql`,
headers: {
Authorization: `Bearer ${token}`
}
});
// create an inmemory cache instance for caching graphql data
const cache = new InMemoryCache()
// instantiate apollo client with apollo link instance and cache instance
const client = new ApolloClient({
link: link as any,
cache
});
return client;
}
export default makeApolloClient;
- ran
npx react-native run-android
.
Versions
System:
OS: Windows 10 10.0.19042
Binaries:
Node: 12.18.2 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.5 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm: 6.14.5 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: 86.0.4240.111
Edge: Spartan (44.19041.423.0), Chromium (86.0.622.51), ChromiumDev (88.0.673.0)
npmPackages:
@apollo/client: 3.2.0 => 3.2.0
I actually downgraded @apollo/client from 3.2.4 to test this. Both of the versions did not work.
@karansinghgit This part looks a bit off to me:
let [client, setClient] = React.useState({} as ApolloClient<any>);
client = makeApolloClient("...");
setClient(client);
This means you're making a new ApolloClient
instance every time you render the component, and then triggering another rerender by calling setClient
. Is that really what you want?
no, I don't mean to do that. I refactored the code to one without any state, but still get the same error.
@karansinghgit Ahh, I think the problem is that you're calling useQuery
before you've created your <ApolloProvider client={client}/>
component, so useQuery
can't find any ApolloProvider
above it in the component tree, and thus can't find the client
. I think you might want to move the client creation and ApolloProvider
wrapping code out of your App
component, so the App
component can safely call useQuery
. If that's not an option, you can move the useQuery
code down into a nested component that's rendered inside the <ApolloProvider/>
component.
@benjamn @karansinghgit I'm having the exact same issue with the exact same setup. I was trying to connect with Hasura using Apollo client following their docs. But unlike the above example, I'm calling the useQuery somewhere down in the nested components. (The useQuery call is in a child component not in the App.js file, and also I wrapped the whole navigator inside the <ApolloProvider>
)
Code
const query = gql`
query menu {
dish {
dish_id
name
}
}
`;
const { data, error, loading } = useQuery(query);
console.log(JSON.stringify(data, null, 2));
This is giving me the error
But if I use this code instead, I can see the items logging into the console.
<ApolloConsumer>
{(client) => {
client.query({
query
})
.then(({ data: G_DATA, loading, error }) => {
console.log(JSON.stringify(G_DATA, null, 2));
})
.catch((error) => {
console.log('Error', error);
});
return {... Other Child components here}
}
</ApolloConsumer>
Can you tell me what I'm doing wrong with useQuery hook. TIA
Update: Previously I was using @apollo/client version 3.2.5. I downgraded it to 3.2.1 and the useQuery is working.
@An0r4k the suggestion provided by @benjamn worked for me.
My current App.tsx
looks like:
import React from "react";
import { RootProvider } from './src/navigation';
export default function App() {
return (
<RootProvider />
);
}
where RootProvider
element is in another file:
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import RootNavigator from './RootNavigator';
import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client";
const client = new ApolloClient({
uri: 'MY_HASURA_INSTANCE_URL',
headers: {
'x-hasura-admin-secret': 'MYADMINSECRETKEY'
},
cache: new InMemoryCache()
});
export function Navigation() {
return (
<NavigationContainer>
<RootNavigator />
</NavigationContainer>
);
};
export function RootProvider() {
return (
<ApolloProvider client={client}>
< Navigation />
</ApolloProvider>
);
}
same problem here..
same problem
@karansinghgit Ahh, I think the problem is that you're calling
useQuery
before you've created your<ApolloProvider client={client}/>
component, souseQuery
can't find anyApolloProvider
above it in the component tree, and thus can't find theclient
. I think you might want to move the client creation andApolloProvider
wrapping code out of yourApp
component, so theApp
component can safely calluseQuery
. If that's not an option, you can move theuseQuery
code down into a nested component that's rendered inside the<ApolloProvider/>
component.
Thank you for sharing this! I used this approach and resolved the issue 👍
same problem from version 3.8.9. In version 3.8.8 all ok
Today I also got into this trap, though I "thought" that I did follow their tutorial very carefully :))
But the trick is, you need to use the useQuery
in a child component of where you wrap with <ApolloProvider client={client}>
In their Quick Started guide, they have to use useQuery
inside of the ExchangeRates
component: https://www.apollographql.com/docs/react/get-started/#request-data
Exactly the same problem, just happened with no updates or changes. First disappears when the cache is cleaned but then on next page render its back.
Using "react-apollo": "^2.5.2",
import client from './api/Apollo' // This is fine..
<I18nextProvider i18n={i18n}>
<ApolloProvider client={client}>
client is a successful import and is there, no lint errors no runtime errors, just this, and its turning out to be pretty serious issue
Could not find "client" in the context of ApolloConsumer. Wrap the root component in an <ApolloProvider>
There is no option to up or downgrade for various reasons.
@stevematdavies are you using @apollo/react-components, @apollo/react-hoc, @apollo/react-ssr, @apollo/react-testing, @apollo/react-hooks?
@davidcostadev none of those
It's possible the error is related to package version mismatches.
I decided to try @apollo/client@^3.4.0-beta.19
and I ran into this issue. In my case I think I had two issues:
- I am using yarn workspaces and
lerna
and my projects rootpackage.json
was resolving to an older version of@apollo/client
~~even after a clean bootstrap. Setting the@apollo/client
version in the rootdependencies
fixed this - though the next step may have made this unnecessary.~~ - Assuming other
apollo
packages are relying on an older@apollo/client
, they may not be resolving correctly. ~~I am usingwebpack
, and to ensure all packages resolve to the same@apollo/client
, I added an alias to my config. Something like the following inwebpack.config.js
:~~
~~webpack.resolve.alias: { '@apollo/client': path.resolve(__dirname, 'node_modules', '@apollo', 'client') }~~
~~I no longer have the error.~~
EDIT:
Thanks to this comment on a related type issue I was having, I instead opted to use yarns resolution
in the root package.json
instead of the above two more complicated steps.
/* package.json */
...
"resolutions": {
"@apollo/client": "^3.4.0-beta.19"
},
...
I no longer have the error and my type errors are gone.
@wallzero I am using yarn v2 workspaces, pnp.
Had to add such config in yarnrc.yml in order to fix ambigous react and graphql dependencies:
packageExtensions:
"@apollo/client@*":
dependencies:
react: "^17.0.1"
graphql: "^15.5.0"
Tried your solution also still the same error, very annoying...
After long hours i figured out this nonesense https://github.com/apollographql/apollo-client/issues/7112#issuecomment-702884623 works. This project starting to become ridiculous. @apollo/client@^3.4.0-beta.20
Similar to what others mentioned, I had this issue with subscriptions.
Doesn't work: import { useSubscription } from '@apollo/client/react/hooks/useSubscription';
Works: import { useSubscription } from '@apollo/client';
I am also encountering this issue.
In my case, it is not due to the use of outdated libraries (all of my imports are from @apollo/client@latest
).
If I use a hook (e.g. useMutation
) in a nextjs page
, everything works fine.
If, however, I move that useMutation()
call to one of that page's children, I get the referenced error.
I don't know how react context plays with nextjs, and nextjs' nightmare of a routing system probably messes with things, but my understanding is that ApolloProvider
should provide the client
to any children components (without HOCs, which aren't exactly best-practices any longer and add extra boilerplate, something Apollo has enough of already cough list insert cache updates cough), so I'm not sure why it's not working. Obviously, calling all my Apollo hooks in root page components isn't a viable long-term solution, so I hope someone who understands the intricacies of how these two libraries are meant to interact can shine some light onto the situation.
I wonder if this helps but for me it ended up being because I had two different versions of apollo/client installed somehow. Verified by checking my yarn.lock
and getting rid of the duplicate.
I got the issue, but my problem was using different graphql versions in a monorepo.
It's possible the error is related to package version mismatches.
I decided to try
@apollo/client@^3.4.0-beta.19
and I ran into this issue. In my case I think I had two issues:
- I am using yarn workspaces and
lerna
and my projects rootpackage.json
was resolving to an older version of@apollo/client
~even after a clean bootstrap. Setting the@apollo/client
version in the rootdependencies
fixed this - though the next step may have made this unnecessary.~- Assuming other
apollo
packages are relying on an older@apollo/client
, they may not be resolving correctly. ~I am usingwebpack
, and to ensure all packages resolve to the same@apollo/client
, I added an alias to my config. Something like the following inwebpack.config.js
:~~webpack.resolve.alias: { '@apollo/client': path.resolve(__dirname, 'node_modules', '@apollo', 'client') }~
~I no longer have the error.~
EDIT:
Thanks to this comment on a related type issue I was having, I instead opted to use yarnsresolution
in the rootpackage.json
instead of the above two more complicated steps./* package.json */ ... "resolutions": { "@apollo/client": "^3.4.0-beta.19" }, ...
I no longer have the error and my type errors are gone.
Thanks Worked for me!
After long hours i figured out this nonesense #7112 (comment) works. This project starting to become ridiculous. @apollo/client@^3.4.0-beta.20
This worked for me as well
Some of my tests were failing after upgrading some packages, so I went to check which ones and I managed to get my tests passing after downgrading to v3.4
.
npm i @apollo/[email protected]
We have a case where the usage of a GQL query is based on a feature flag. The component renders like this (simplified):
if (enabled) return <ApolloProvider client={client}>{children}</ApolloProvider>
else return children;
One of the child components have a hook that calls useLazyQuery
. Since hooks can't be in if-statements, the hook is always called, but when the flag is off, we never execute the query. Something like this:
function customHook(enabled) {
const [executeQuery] = useLazyQuery(gql`...`);
const search = (input) => {
if (enabled) return executeQuery(input);
else return Promise.resolve();
}
return search;
}
When we were on version 3.3.15, it worked without problems, but after upgrading to 3.5.10 useLazyQuery
throws the error about missing apollo client. Is there a simple way to avoid this? Or do we have to refactor our code to avoid calling the hook completely in this case?
Only got Nextjs 13 to work with apollo with app directory with this howto https://blog.logrocket.com/why-use-next-js-apollo/
I think this deviated very far from the original issue, and that one seems solved - so I'm going to close this issue.
Generally, if you are a reader from the future, there can be multiple reasons for this error:
- You are using an Apollo hook in a component that is not wrapped in an ApolloProvider component. That also includes the component with the ApolloProvider itself - you can only use the hooks in children of that.
- You have multiple different versions of Apollo Client in your bundle.
You can do a
npm why @apollo/client
oryarn why @apollo/client
to find out if that is the case. - You are using Next.js with the Pages router. In that case, take a look at the Next.js example for using Apollo Client with the pages router
- If you are using Next.js with React Server Components and the App directory, things work differently there, too. See this README
I had issues with how I was doing the initial Nextjs installation with the App dir n the AppRouter components n yet _app.js use the Pages Router if not mistaken. Thank you so for your help
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. For general questions, we recommend using StackOverflow or our discord server.