I'm using Yarn v2 (berry) to manage a monorepo with the following structure:
project-root
/packages
react-native-app
(dependencies: my-hooks-lib, [email protected])
my-hooks-lib
(dependency: [email protected])
Here's my .yarnrc.yml:
yarnPath: ".yarn/releases/yarn-berry.cjs"
nodeLinker: "node-modules"
nmHoistingLimits: "workspaces"
I've disabled hoisting since I'm working with a React Native app. But because of this, react-native-app
and my-hooks-lib
have separate copies of [email protected]
, even though the versions are the same. This results in a Invalid Hooks call
error:
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 is because my-hooks-lib
uses a different copy of React, even though the version is the same. It works fine if I import React like this:
// inside my-hooks-lib
import React from "../react-native-app/node_modules/react";
I made React a peer-dependency inside my-hooks-lib
, but that didn't help either, since Yarn creates a symlink to my-hooks-lib
inside react-native-app
, but it isn't able to resolve React. I then installed React as a dev-dependency at the root of my project, and now I'm back to my original problem, since now my-hooks-lib
refers to the copy of React at the project root.
Is there a way to fix this during development?
Update: As a workaround, I've made React as a peer-dependency for both react-native-app
and my-hooks-lib
, and added React as a dev-dependency at the project root. So this is what it looks like now:
<project-root>
(dev-dependency: [email protected])
/packages
/react-native-app
(dependency: my-hooks-lib, peer-dependency: [email protected])
/my-hooks-lib
(peer-dependency: [email protected])
Although I'd still love to hear a better solution!