I'm developing a React library for my common used components. In my root folder where there is:
- my rollup config and my
src/
folder containing my library. When it's build, the bundle files (ES, CJS and UMD) are in thedist/
folder. - my workspace: a simple
parcel
bundled app where there is an independentpackage.json
. In thispackage.json
, myLib is in dependencies and I linked it.
When I want to use myLib in the workspace I import it like this: import { Button } from 'myLib'
.
Here, everything seems to be okay. But in a component I'm using a hook and I have this error:
Uncaught Invariant Violation: 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
It seems there's two copies of React, npm ls react
returns:
└─┬ [email protected] invalid
└── [email protected] extraneous
I tried to link react and react-dom between myLib/
and workspace/
node_modules but it never works and this error is still here.
TLDR;
Here's my file tree:
myLib
│ package.json
│ rollup.config.js
│
└───dist/
│
└───src/
│ │ **
│
└───workspace
│ │ package.json
│ │ index.js
To link myLib to workspace: I go to myLib/
and I do yarn link
then I go to workspace/
and I do yarn link myLib
react and react-dom are peerDependencies in myLib
and devDependencies in workspace/
Oh course I already looked here:
- .html
I'm developing a React library for my common used components. In my root folder where there is:
- my rollup config and my
src/
folder containing my library. When it's build, the bundle files (ES, CJS and UMD) are in thedist/
folder. - my workspace: a simple
parcel
bundled app where there is an independentpackage.json
. In thispackage.json
, myLib is in dependencies and I linked it.
When I want to use myLib in the workspace I import it like this: import { Button } from 'myLib'
.
Here, everything seems to be okay. But in a component I'm using a hook and I have this error:
Uncaught Invariant Violation: 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
It seems there's two copies of React, npm ls react
returns:
└─┬ [email protected] invalid
└── [email protected] extraneous
I tried to link react and react-dom between myLib/
and workspace/
node_modules but it never works and this error is still here.
TLDR;
Here's my file tree:
myLib
│ package.json
│ rollup.config.js
│
└───dist/
│
└───src/
│ │ **
│
└───workspace
│ │ package.json
│ │ index.js
To link myLib to workspace: I go to myLib/
and I do yarn link
then I go to workspace/
and I do yarn link myLib
react and react-dom are peerDependencies in myLib
and devDependencies in workspace/
Oh course I already looked here:
- https://reactjs.org/warnings/invalid-hook-call-warning.html
- https://github.com/facebook/react/issues/13991
- https://github.com/facebook/react/issues/15315
- https://github.com/facebook/react/issues/15628
3 Answers
Reset to default 10Here is a simple solution that works with yarn and npm:
cd /your-library/node_modules/react
yarn link
cd /your-library/node_modules/react-dom
yarn link
cd /your-app
yarn link react
yarn link react-dom
Ensure that your-library
has React version compatible with your-app
.
Alternatively, if you are using webpack, just configure alias:
alias: {
react: path.resolve(__dirname, './node_modules/react'),
'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
},
The solution for this issue is actually explained in the react doc:
This problem can also come up when you use npm link or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder. Assuming myapp and mylib are sibling folders, one possible fix is to run
npm link ../myapp/node_modules/react
from mylib. This should make the library use the application’s React copy.
Another solution is to use lerna (with hoisting).
I found an answer that worked for me here: How to avoid React loading twice with Webpack when developing
I spent a bit of time with this problem, yet the answer was simple. If you are having multiple versions of React, you have to go to your workspace and link to the version of React in myLib.