apollo-client
apollo-client copied to clipboard
Invalid hook call when used inside React Native
Feels like I'm going crazy about this issue. I'm currently using @apollo/client
with react-native
in a yarn workspace. I've setup the yarn workspace correctly with the custom metro config required, and the nohoist options. Here are my configs:
"workspaces": {
"nohoist": [
"@react-native-community/async-storage",
"react-native",
"react-native/**",
"react-native-dev-menu",
"react-native-svg",
"jetifier",
"react-native-gesture-handler",
"@apollo/client",
"react"
]
},
"resolutions": {
"@types/react": "^17",
"react": "17.0.2",
"@apollo/client": "3.3.21"
},
"dependencies": {
"react": "17.0.2",
"@apollo/client": "3.3.21"
// ...
}
const getWorkspaces = require("get-yarn-workspaces");
const path = require("path");
function getConfig(appDir) {
const workspaces = getWorkspaces(appDir);
const watchFolders = [
...workspaces.filter((workspaceDir) => !(workspaceDir === appDir)),
path.resolve(appDir, "node_modules"),
path.resolve(appDir, "..", "node_modules"),
];
return {
watchFolders,
resolver: {
extraNodeModules: {
"react-native": path.resolve(appDir, "node_modules", "react-native"),
react: path.resolve(appDir, "node_modules", "react"),
"react-native-svg": path.resolve(appDir, "node_modules", "react-native-svg"),
"core-js": path.resolve(appDir, "node_modules", "core-js"),
"@apollo/client": path.resolve(appDir, "node_modules", "@apollo", "client"),
},
},
};
}
module.exports = getConfig(__dirname);
This works as expected, and normal React hooks works. But using useQuery
gives me:
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
This error is located at:
in AppInner (at App.tsx:44)
in ApolloProvider (at App.tsx:43)
in App (at renderApplication.js:47)
...
My application code is:
import { AppRegistry } from "react-native";
import { App } from "./src/components/App";
import { name as appName } from "./app.json";
import "react-native-gesture-handler";
AppRegistry.registerComponent(appName, () => App);
import React, { useCallback, useContext, useEffect } from "react";
import { Text } from "react-native";
import {
ApolloClient,
ApolloProvider,
useQuery,
} from "@apollo/client";
import { useQueryHookFromOtherPackage } "@propty/code/src/generated"
const client = new ApolloClient({
// ...
});
export const App: React.FC = () => {
return (
<ApolloProvider client={client}>
<AppInner />
</ApolloProvider>
);
};
const AppInner: React.FC = () => {
// This hook is generated using GraphQL code generation in a package inside our yarn workspace
useQueryHookFromOtherPackage()
return <Text>test</Text>
It seems like it's specifically the useQuery
hook that breaks, as other hooks there works fine.
I've checked and @apollo/client
and react
are also properly hoisted, meaning they should not be any weird version issues.
@Cretezy Can you run npm ls react react-dom
and share the output?
Alternatively/additionally, Apollo Client v3.4 is very close to release, and some aspects of importing/exporting React stuff have changed internally, so there's always a chance updating with
npm i @apollo/client@beta
could solve some problems.
@benjamn
➜ yarn why react
yarn why v1.22.10
[1/4] Why do we have the module "react"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "[email protected]"
info Reasons this module exists
- "_project_#@propty#frontends-mobile" depends on it
- Hoisted from "_project_#@propty#frontends-mobile#react"
- Hoisted from "_project_#@propty#frontends-web#react"
- Hoisted from "_project_#@propty#frontends-storybook#react"
info Disk size without dependencies: "356KB"
info Disk size with unique dependencies: "404KB"
info Disk size with transitive dependencies: "432KB"
info Number of shared dependencies: 3
Done in 0.98s.
➜ yarn why react-dom
yarn why v1.22.10
[1/4] Why do we have the module "react-dom"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
[4/4] Calculating file sizes...
=> Found "[email protected]"
info Reasons this module exists
- "_project_#@propty#frontends-web" depends on it
- Hoisted from "_project_#@propty#frontends-web#react-dom"
- Hoisted from "_project_#@propty#frontends-storybook#react-dom"
info Disk size without dependencies: "2.93MB"
info Disk size with unique dependencies: "3.18MB"
info Disk size with transitive dependencies: "3.21MB"
info Number of shared dependencies: 4
Done in 0.72s.
➜ npm ls react react-dom
@propty/[email protected] /.../frontends/mobile
└── (empty)
@benjamn No luck with @apollo/[email protected]
either
Okay narrowed it down a little.
My original code of using the following works:
useQuery(gql`
query {
me {
id
}
}
`);
However, using a generated hook from the GraphQL code gen, imported from a package in the workspace, does not. We have a package (@propty/core
) in the workspace where the .graphql
files are, and where the code gen happens. We import this package on our web/mobile packages. I've updated the OP with the "real" example (importing a generated hook)
I've tried unhoisting @apollo/client
with no success.
Any ideas?
having the same issue
I've found the source of the problem.
My current yarn workspace looks like:
-
/
: The root-
core
: Where the Apollo Hooks are generated -
mobile
: The React Native applications that's problematic -
web
-
Inside mobile/package.json
, I have:
"workspaces": {
"nohoist": [
"**/*"
]
},
And in /package.json
, I have:
"workspaces": {
"packages": [
"web",
"mobile",
"core"
],
"nohoist": [
"**/react",
"**/react/**",
"**/@apollo/client",
"**/@apollo/client/**"
]
},
The problem
My core
package has @apollo/client
as a devDependency (mobile
also has it). When I remove @apollo/client
from the core
's devDependency, I can use the hooks correctly.
This doesn't seem to be strictly a problem with @apollo/client
, but more of a Metro/React Native issue.
No matter what I do, as long as @apollo/client
is in the devDependencies, this error appears.
Currently using @apollo/[email protected]
. Still getting the same error as OP.